summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSunil Shetye2025-03-17 15:51:20 +0530
committerSunil Shetye2025-03-17 15:51:20 +0530
commit9dae2503fef590a973bd2f949de1bf2b9132ea81 (patch)
tree0f34256b928e2ad0be8a4898c2b1f8e887d04d53
parentaf35c90573c9e91428b195913565697118150ddf (diff)
downloadCommon-Interface-Project-9dae2503fef590a973bd2f949de1bf2b9132ea81.tar.gz
Common-Interface-Project-9dae2503fef590a973bd2f949de1bf2b9132ea81.tar.bz2
Common-Interface-Project-9dae2503fef590a973bd2f949de1bf2b9132ea81.zip
add script_dump column from xcos_on_cloud
-rw-r--r--blocks/saveAPI/fixtures/saveAPI.yaml24595
1 files changed, 24284 insertions, 311 deletions
diff --git a/blocks/saveAPI/fixtures/saveAPI.yaml b/blocks/saveAPI/fixtures/saveAPI.yaml
index 3a0e7e64..cacb8790 100644
--- a/blocks/saveAPI/fixtures/saveAPI.yaml
+++ b/blocks/saveAPI/fixtures/saveAPI.yaml
@@ -69,13 +69,13 @@
fields:
category_name: Power Systems
- model: saveAPI.gallery
- pk: 622
+ pk: 1
fields:
save_id: gallery0
name: ch5_1
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 5) Analysis
Methods, 5.1) The branch current method'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="ch51.scos"><!--Xcos - 1.0 - scilab-5.5.2
@@ -1054,14 +1054,15 @@
x="300.0" y="190.0"/></Array></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="-5c1d823d:130d68ab7d2:-7f7c" parent="-5c1d823d:130d68ab7d2:-7f7b"/></XcosDiagram>
media: gallery0.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 623
+ pk: 2
fields:
save_id: gallery1
name: ch5_6
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 5) Analysis
Methods, 5.6) Network reduction'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ch5_6"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -2727,14 +2728,15 @@
scilabClass="ScilabList"><mxPoint x="630.0" y="450.0"/><mxPoint x="630.0" y="410.0"/></Array></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="331568f2:130d6f18fe2:-8000" parent="331568f2:130d6f18fe2:-7fff"/></XcosDiagram>
media: gallery1.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 624
+ pk: 3
fields:
save_id: gallery2
name: ch5_7
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 5) Analysis
Methods, 5.7) Superposition'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ch5_7"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -3634,14 +3636,15 @@
x="844.0" y="90.0"/><mxPoint as="targetPoint" x="880.0" y="90.0"/></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="331568f2:130d6f18fe2:-7db5" parent="331568f2:130d6f18fe2:-7db4"/></XcosDiagram>
media: gallery2.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 625
+ pk: 4
fields:
save_id: gallery3
name: ch6_11
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 6) Amplifiers
and Operational Amplifiers, 6.11) Noninverting circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="ch611"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -4342,14 +4345,15 @@
x="640.0" y="200.0"/></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="-55de3cf2:130fe0d1e6e:-7e33" parent="-55de3cf2:130fe0d1e6e:-7e32"/></XcosDiagram>
media: gallery3.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 626
+ pk: 5
fields:
save_id: gallery4
name: ch6_15
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 6) Amplifiers
and Operational Amplifiers, 6.15) Circuits containing several Op amps'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ch6_15"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -5502,14 +5506,15 @@
x="584.0" y="180.0"/><mxPoint as="targetPoint" x="610.0" y="180.0"/></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="-1e985524:130d9355380:-8000" parent="-1e985524:130d9355380:-7fff"/></XcosDiagram>
media: gallery4.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 627
+ pk: 6
fields:
save_id: gallery5
name: ch6_9
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 6) Amplifiers
and Operational Amplifiers, 6.9) Analysis of circuits containing ideal op amps'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ch6_9"><!--Xcos - 1.0 - scilab-5.5.2 - 20150331
@@ -7439,14 +7444,15 @@
scilabClass="ScilabList"><mxPoint x="740.0" y="170.0"/><mxPoint x="740.0" y="130.0"/></Array></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="5678f95b:130d8f27016:-8000" parent="5678f95b:130d8f27016:-7fff"/></XcosDiagram>
media: gallery5.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 628
+ pk: 7
fields:
save_id: gallery6
name: ch8_2
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 8) First
order Circuits, 8.2) Capacitor Discharge in a Resistor'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.05" title="ch8_2"><!--Xcos - 1.0 - scilab-5.5.2 - 20150331
@@ -7976,14 +7982,15 @@
scilabClass="ScilabList"><mxPoint x="120.0" y="110.0"/></Array></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-1e985524:130d9355380:-7dc3" parent="-1e985524:130d9355380:-7dc2"/></XcosDiagram>
media: gallery6.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 629
+ pk: 8
fields:
save_id: gallery7
name: ch8_3
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 8) First
order Circuits, 8.3) Establishing a DC Voltage across a Capacitor'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.1" title="ch8_3"><!--Xcos - 1.0 - scilab-5.5.2 - 20150331
@@ -8549,14 +8556,15 @@
x="430.0" y="84.0"/><mxPoint as="targetPoint" x="430.0" y="150.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-1e985524:130d9355380:-7d28" parent="-1e985524:130d9355380:-7d27"/></XcosDiagram>
media: gallery7.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 630
+ pk: 9
fields:
save_id: gallery8
name: ch8_4
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 8) First
order Circuits, 8.4) The Source free RL Circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.1" title="ch8_4"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -9606,14 +9614,15 @@
x="-8.0" y="6.0"/></ExplicitInputPort></root></mxGraphModel><mxCell as="defaultParent"
id="-1e985524:130d9355380:-7b0d" parent="-1e985524:130d9355380:-7b0c"/></XcosDiagram>
media: gallery8.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 631
+ pk: 10
fields:
save_id: gallery9
name: ch8_5
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 8) First
order Circuits, 8.5) Complex first order RL and RC Circuits'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="ch8_5"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -10534,14 +10543,15 @@
as="geometry" height="8.0" width="8.0" x="16.0" y="40.0"/></ImplicitOutputPort></root></mxGraphModel><mxCell
as="defaultParent" id="-5c3e5c92:130db8fddce:-8000" parent="-5c3e5c92:130db8fddce:-7fff"/></XcosDiagram>
media: gallery9.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 632
+ pk: 11
fields:
save_id: gallery10
name: ch8_6
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 8) First
order Circuits, 8.6) Complex first order RL and RC Circuits'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="1.0" title="ch8_6"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -12375,14 +12385,15 @@
x="210.0" y="190.0"/><mxPoint x="210.0" y="190.0"/><mxPoint x="160.0" y="190.0"/></Array></mxGeometry></ImplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="31befcfe:130dc407023:-8000" parent="31befcfe:130dc407023:-7fff"/></XcosDiagram>
media: gallery10.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 633
+ pk: 12
fields:
save_id: gallery11
name: ch8_7
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 8) First
order Circuits, 8.7) DC Steady state in Inductors and Capacitors'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="ch8_7"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -13548,14 +13559,15 @@
as="defaultParent" id="31befcfe:130dc407023:-7d8a" parent="31befcfe:130dc407023:-7d89"/><mxPoint
as="origin" x="-6.0" y="-6.0"/></XcosDiagram>
media: gallery11.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 634
+ pk: 13
fields:
save_id: gallery12
name: ch8_8
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 8) First
order Circuits, 8.8) DC Steady state in Inductors and Capacitors'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
title="ch8_8"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406 2040--><mxGraphModel
@@ -14320,14 +14332,15 @@
as="targetPoint" x="360.0" y="360.0"/></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="4cf3be04:130e07e353b:-8000" parent="4cf3be04:130e07e353b:-7fff"/></XcosDiagram>
media: gallery12.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 635
+ pk: 14
fields:
save_id: gallery13
name: ch8_9
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 8) First
order Circuits, 8.9) Transitions at Switching Time'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0" title="ch8_9"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -15602,14 +15615,15 @@
x="400.0" y="370.0"/></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="0:2:0" parent="0:1:0"/></XcosDiagram>
media: gallery13.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 636
+ pk: 15
fields:
save_id: gallery14
name: ch9_1
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 9) Higher
order circuits and Complex frequency, 9.1) Series RLC Circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
cellsLocked="1" finalIntegrationTime="0.05" title="ch9_1"><!--Xcos - 1.0 - scilab-5.5.2
@@ -16106,14 +16120,15 @@
x="400.0" y="290.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="5f267dc3:130e0981282:-8000" parent="5f267dc3:130e0981282:-7fff"/></XcosDiagram>
media: gallery14.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 637
+ pk: 16
fields:
save_id: gallery15
name: ch9_2
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 9) Higher
order circuits and Complex frequency, 9.2) Series RLC Circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.05" title="ch9_2"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -16612,14 +16627,15 @@
as="geometry" height="8.0" width="8.0" x="40.0" y="16.0"/></ImplicitOutputPort></root></mxGraphModel><mxCell
as="defaultParent" id="5f267dc3:130e0981282:-7ebc" parent="5f267dc3:130e0981282:-7ebb"/></XcosDiagram>
media: gallery15.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 638
+ pk: 17
fields:
save_id: gallery16
name: ch9_5
description: 'Electric Circuits (Author: M. Navhi And J. A. Edminister), 9) Higher
order circuits and Complex frequency, 9.5) Parallel RLC circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 154
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="1.0" title="ch9_5"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -17181,14 +17197,15 @@
x="380.0" y="240.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="5f267dc3:130e0981282:-7d6d" parent="5f267dc3:130e0981282:-7d6c"/></XcosDiagram>
media: gallery16.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 639
+ pk: 18
fields:
save_id: gallery17
name: example3_27
description: 'Basic Electronics (Author: D. De), 3) Diode Circuits, 3.27) Find
currents and voltages'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 181
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="Ex3_27"><!--Xcos - 1.0 - scilab-5.5.2 - 20150331
@@ -17910,14 +17927,53 @@
y="20.0"/><mxPoint x="240.0" y="20.0"/></Array></mxGeometry></ImplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="-3721ad33:1314dc6b131:-8000" parent="-3721ad33:1314dc6b131:-7fff"/></XcosDiagram>
media: gallery17.png
+ script_dump: '// Find currents and voltages
+
+ // Basic Electronics
+
+ // By Debashis De
+
+ // First Edition, 2010
+
+ // Dorling Kindersley Pvt. Ltd. India
+
+ // Example 3-27 in page 179
+
+
+ // Given data
+
+ //Diode acts as short circuited.Both diodes are forward biased
+
+ V1=0; // Voltage at junction 1 in V
+
+ V2=0; // Voltage at junction 2 in V
+
+
+ //Calculation
+
+ I1=(20-V1)/(20*10^3);
+
+ I2=(V2-(-10))/(20*10^3);
+
+
+ printf("I1 = %0.0e A\n",I1);
+
+ printf("I2 = %0.1e A",I2);
+
+
+ // Result
+
+ // I1 = 1 mA
+
+ // I2 = 0.5 mA'
- model: saveAPI.gallery
- pk: 640
+ pk: 19
fields:
save_id: gallery18
name: example3_28
description: 'Basic Electronics (Author: D. De), 3) Diode Circuits, 3.28) Find
voltage across diode'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 181
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
title="example3_28"><!--Xcos - 1.0 - scilab-5.5.2 - 20200302--><mxGraphModel
@@ -18473,14 +18529,44 @@
y="470.0"/><mxPoint x="510.0" y="200.0"/></Array></mxGeometry></ImplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="-3721ad33:1314dc6b131:-7f87" parent="-3721ad33:1314dc6b131:-7f86"/></XcosDiagram>
media: gallery18.png
+ script_dump: '// Find voltage across diode
+
+ // Basic Electronics
+
+ // By Debashis De
+
+ // First Edition, 2010
+
+ // Dorling Kindersley Pvt. Ltd. India
+
+ // Example 3-28 in page 180
+
+
+ // Given data
+
+ I=0.1075; // Cirremt across diode in A
+
+ Rd=1; // Internal resistance of diode in ohm
+
+
+ // Calculation
+
+ Vd=I*Rd;
+
+ printf("Voltage across diode = %0.4f V",Vd);
+
+
+ // Result
+
+ // Voltage across diode = 0.1075 V'
- model: saveAPI.gallery
- pk: 641
+ pk: 20
fields:
save_id: gallery19
name: example3_30
description: 'Basic Electronics (Author: D. De), 3) Diode Circuits, 3.30) Calculate
R Il max'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:07+00:00
book: 181
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="Ex3_30"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -19120,14 +19206,52 @@
x="780.0" y="130.0"/><mxPoint as="targetPoint" x="780.0" y="180.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-3721ad33:1314dc6b131:-7f5d" parent="-3721ad33:1314dc6b131:-7f5c"/></XcosDiagram>
media: gallery19.png
+ script_dump: '// Calculate R,I_l(max)
+
+ // Basic Electronics
+
+ // By Debashis De
+
+ // First Edition, 2010
+
+ // Dorling Kindersley Pvt. Ltd. India
+
+ // Example 3-30 in page 181
+
+
+ // Given data
+
+ V_0=50; // Zener diode voltage in V
+
+ I_L=0; // Load current in A
+
+
+ // Calculation
+
+ R=(150)/(40*10^-3);
+
+ printf("(a)R = %0.2e ohm\n",R);
+
+ printf("I_L = I_max when Id = Id_min = 10mA\n");
+
+ I_Lmax=40-10;
+
+ printf("(b)Maximum load current = %0.0f mA",I_Lmax);
+
+
+ // Result
+
+ // (a) R = 3.75 K-ohms
+
+ // (b) I_Lmax = 30 mA'
- model: saveAPI.gallery
- pk: 642
+ pk: 21
fields:
save_id: gallery20
name: example3_8
description: 'Basic Electronics (Author: D. De), 3) Diode Circuits, 3.8) Calculate
the dc load current'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 181
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
title="Ex3_8"><!--Xcos - 1.0 - scilab-5.5.2 - 20150331 1216--><mxGraphModel
@@ -19793,14 +19917,71 @@
x="870.0" y="200.0"/><mxPoint x="740.0" y="200.0"/></Array></mxGeometry></ImplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="-2d85d470:1314777ee15:-7f7e" parent="-2d85d470:1314777ee15:-7f7d"/></XcosDiagram>
media: gallery20.png
+ script_dump: '// Calculate the dc load current
+
+ // Basic Electronics
+
+ // By Debashis De
+
+ // First Edition, 2010
+
+ // Dorling Kindersley Pvt. Ltd. India
+
+ // Example 3-8 in page 157
+
+
+ // Given data
+
+ Vm=280; // Supply voltage in V
+
+ Rl=2000; // Load resistance in ohms
+
+ Rf=500; // Internal resistance of the diodes in ohms
+
+
+ // Calculation
+
+ Idc=(2*Vm)/(%pi*2500);
+
+ Idc_t=Idc/2;
+
+ printf("(a)I_dc = %0.2e A\n(b)I_dc(tube) = %0.2e A\n",Idc,Idc_t);
+
+ printf("(c)Voltage across conducting diode is sinusoidal with a peak value 0.2
+ Vm\n");
+
+ V_rms=0.905*(280*sqrt(2));
+
+ Pdc=Idc^2*Rl;
+
+ R=(Rf/Rl)*100;
+
+ printf("Rms voltage V_rms = %0.0f V\n",V_rms);
+
+ printf("(d)DC output power = %0.1f W\n",Pdc);
+
+ printf("(e)Percentage regulation = %0.0f percent",R);
+
+
+ // Result
+
+ // (a) Idc = 71 mA,
+
+ // (b) Idc_tube = 35.7 mA,
+
+ // (c) V_rms = 358 V,
+
+ // (d) P_dc = 10.167W,
+
+ // (e) Percentage regulation = 25%'
- model: saveAPI.gallery
- pk: 643
+ pk: 22
fields:
save_id: gallery21
name: Ex10_1
description: 'Digital Control (Author: K. M. Moudgalya), 10) Special Cases of
Pole Placement Control, 10.1) Effect of delay in control performance'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="20.0" title="stb_disc"><!--Xcos - 1.0 - scilab-5.5.2 -
@@ -22203,14 +22384,1082 @@
as="geometry" height="40.0" width="40.0" x="40.0" y="320.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-7476484f:145f8cd2a3c:-7be9" parent="-7476484f:145f8cd2a3c:-7be8"/></XcosDiagram>
media: gallery21.png
+ script_dump: '// Effect of delay in control performance
+
+ // 10.1
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+ // Pole placement controller using internal model principle, as discussed in
+ Sec. 9.4.
+
+ // 9.8
+
+
+ // function [Rc,Sc,Tc,gamma,phit] = pp_im(B,A,k,phi,Delta)
+
+ // Calculates 2-DOF pole placement controller.
+
+
+ function [Rc,Sc,Tc,gamm] = pp_im(B,A,k,phi,Delta)
+
+
+ // Setting up and solving Aryabhatta identity
+
+ [Ag,Ab] = polsplit3(A); dAb = length(Ab) - 1;
+
+ [Bg,Bb] = polsplit3(B); dBb = length(Bb) - 1;
+
+
+ [zk,dzk] = zpowk(k);
+
+
+ [N,dN] = polmul(Bb,dBb,zk,dzk);
+
+ dDelta = length(Delta)-1;
+
+ [D,dD] = polmul(Ab,dAb,Delta,dDelta);
+
+ dphi = length(phi)-1;
+
+
+ [S1,dS1,R1,dR1] = xdync(N,dN,D,dD,phi,dphi);
+
+
+ // Determination of control law
+
+ Rc = convol(Bg,convol(R1,Delta)); Sc = convol(Ag,S1);
+
+ Tc = Ag; gamm = sum(phi)/sum(Bb);
+
+ endfunction;
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // Procedure to split a polynomial into good and bad factors, as discussed in
+ Sec. 9.5. The factors that have roots outside unit circle or with negative real
+ parts are defined as bad.
+
+ // 9.12
+
+
+ // function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ // Splits a scalar polynomial of z^{-1} into good and bad
+
+ // factors. Input is a polynomial in increasing degree of
+
+ // z^{-1}. Optional input is a, where a <= 1.
+
+ // Factors that have roots outside a circle of radius a or
+
+ // with negative roots will be called bad and the rest
+
+ // good. If a is not specified, it will be assumed as 1.
+
+
+ function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ if argn(2) == 1, a = 1; end
+
+ if a>1 error(''good polynomial also is unstable''); end
+
+ fac1 = poly(fac(length(fac):-1:1),''z'',''coeff'');
+
+ rts = roots(fac1);
+
+ rts = rts(length(rts):-1:1);
+
+
+ // extract good and bad roots
+
+ badindex = mtlb_find((abs(rts)>=a-1.0e-5)|(real(rts)<-0.05));
+
+ badpoly = coeff(poly(rts(badindex),''z''));
+
+ goodindex = mtlb_find((abs(rts)<a-1.0e-5)&(real(rts)>=-0.05));
+
+ goodpoly = coeff(poly(rts(goodindex),''z''));
+
+
+ // scale by equating the largest terms
+
+ [m,index] = max(abs(fac));
+
+ goodbad = convol(goodpoly,badpoly);
+
+ goodbad = goodbad(length(goodbad):-1:1);
+
+ factor1 = fac(index)/goodbad(index);
+
+ goodpoly = goodpoly * factor1;
+
+ goodpoly = goodpoly(length(goodpoly):-1:1);
+
+ badpoly = badpoly(length(badpoly):-1:1);
+
+ endfunction;
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1; end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+ Ts = 1; B = 0.63; A = [1 -0.37];
+
+ k = 5;
+
+ if k<=0, k = 1; end
+
+ [zk,dzk] = zpowk(k);
+
+
+ // Desired transfer function
+
+ phi = [1 -0.5];
+
+ delta = 1; // internal model of step introduced
+
+
+ // Controller design
+
+ [Rc,Sc,Tc,gamm] = pp_im(B,A,k,phi,delta);
+
+
+ // simulation parameters for stb_disc.xcos
+
+ // y1: 0 to 1; u1: 0 to 1.2
+
+ st = 1.0; // desired change in setpoint
+
+ t_init = 0; // simulation start time
+
+ t_final = 20; // simulation end time
+
+
+ // simulation parameters for stb_disc.xcos
+
+ N_var = 0; C = 0; D = 1; N = 1;
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Rcp1,Rcp2] = cosfil_ip(1,Rc); // 1/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Bp,Ap] = cosfil_ip(B,A); // B/A
+
+ [zkp1,zkp2] = cosfil_ip(zk,1); // zk/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D'
- model: saveAPI.gallery
- pk: 644
+ pk: 23
fields:
save_id: gallery22
name: Ex10_2
description: 'Digital Control (Author: K. M. Moudgalya), 10) Special Cases of
Pole Placement Control, 10.2) Smith predictor for paper machine control'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="20.0" title="smith_disc"><!--Xcos - 1.0 - scilab-5.5.2
@@ -24769,14 +26018,1114 @@
as="geometry" height="30.0" width="40.0" x="550.0" y="380.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-5d8a58f8:147c67c0236:-7ffb" parent="-5d8a58f8:147c67c0236:-7ffa"/></XcosDiagram>
media: gallery22.png
+ script_dump: '// Smith predictor for paper machine control in Example 10.2 on
+ page 385.
+
+ // 10.2
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+ function [C,degC] = poladd(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= cB | rA ~= rB
+
+ error(''poladd: Inconsistent dimensions'');
+
+ end
+
+
+ degC = max(degA,degB);
+
+ if degC >= degA
+
+ A = [A zeros(rA,(degC-degA)*cA)];
+
+ end
+
+ if degC >= degB
+
+ B = [B zeros(rB,(degC-degB)*cB)];
+
+ end
+
+ C = A+B;
+
+ endfunction;
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+ // Pole placement controller using internal model principle, as discussed in
+ Sec. 9.4.
+
+ // 9.8
+
+
+ // function [Rc,Sc,Tc,gamma,phit] = pp_im(B,A,k,phi,Delta)
+
+ // Calculates 2-DOF pole placement controller.
+
+
+ function [Rc,Sc,Tc,gamm] = pp_im(B,A,k,phi,Delta)
+
+
+ // Setting up and solving Aryabhatta identity
+
+ [Ag,Ab] = polsplit3(A); dAb = length(Ab) - 1;
+
+ [Bg,Bb] = polsplit3(B); dBb = length(Bb) - 1;
+
+
+ [zk,dzk] = zpowk(k);
+
+
+ [N,dN] = polmul(Bb,dBb,zk,dzk);
+
+ dDelta = length(Delta)-1;
+
+ [D,dD] = polmul(Ab,dAb,Delta,dDelta);
+
+ dphi = length(phi)-1;
+
+
+ [S1,dS1,R1,dR1] = xdync(N,dN,D,dD,phi,dphi);
+
+
+ // Determination of control law
+
+ Rc = convol(Bg,convol(R1,Delta)); Sc = convol(Ag,S1);
+
+ Tc = Ag; gamm = sum(phi)/sum(Bb);
+
+ endfunction;
+
+ // Procedure to split a polynomial into good and bad factors, as discussed in
+ Sec. 9.5. The factors that have roots outside unit circle or with negative real
+ parts are defined as bad.
+
+ // 9.12
+
+
+ // function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ // Splits a scalar polynomial of z^{-1} into good and bad
+
+ // factors. Input is a polynomial in increasing degree of
+
+ // z^{-1}. Optional input is a, where a <= 1.
+
+ // Factors that have roots outside a circle of radius a or
+
+ // with negative roots will be called bad and the rest
+
+ // good. If a is not specified, it will be assumed as 1.
+
+
+ function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ if argn(2) == 1, a = 1; end
+
+ if a>1 error(''good polynomial also is unstable''); end
+
+ fac1 = poly(fac(length(fac):-1:1),''z'',''coeff'');
+
+ rts = roots(fac1);
+
+ rts = rts(length(rts):-1:1);
+
+
+ // extract good and bad roots
+
+ badindex = mtlb_find((abs(rts)>=a-1.0e-5)|(real(rts)<-0.05));
+
+ badpoly = coeff(poly(rts(badindex),''z''));
+
+ goodindex = mtlb_find((abs(rts)<a-1.0e-5)&(real(rts)>=-0.05));
+
+ goodpoly = coeff(poly(rts(goodindex),''z''));
+
+
+ // scale by equating the largest terms
+
+ [m,index] = max(abs(fac));
+
+ goodbad = convol(goodpoly,badpoly);
+
+ goodbad = goodbad(length(goodbad):-1:1);
+
+ factor1 = fac(index)/goodbad(index);
+
+ goodpoly = goodpoly * factor1;
+
+ goodpoly = goodpoly(length(goodpoly):-1:1);
+
+ badpoly = badpoly(length(badpoly):-1:1);
+
+ endfunction;
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1; end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+ Ts = 1; B = 0.63; A = [1 -0.37]; k = 3;
+
+ Bd = convol(B,[0 1]);
+
+ kd = k - 1;
+
+ [zkd,dzkd] = zpowk(kd);
+
+ [mzkd,dmzkd] = poladd(1,0,-zkd,dzkd);
+
+
+ // Desired transfer function
+
+ phi = [1 -0.5]; delta = 1;
+
+
+ // Controller design
+
+ [Rc,Sc,Tc,gamm] = pp_im(B,A,1,phi,delta);
+
+
+ // simulation parameters for smith_disc.xcos
+
+ st = 1.0; // desired change in setpoint
+
+ t_init = 0; // simulation start time
+
+ t_final = 20; // simulation end time
+
+
+ // simulation parameters for smith_disc.xcos
+
+ N_var = 0; C = 0; D = 1; N = 1;
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Rcp1,Rcp2] = cosfil_ip(1,Rc); // 1/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Bdp,Ap] = cosfil_ip(Bd,A); // Bd/Ad
+
+ [zkdp1,zkdp2] = cosfil_ip(zkd,1); // zkd/1
+
+ [mzkdp1,mzkdp2] = cosfil_ip(mzkd,1); // mzkd/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D'
- model: saveAPI.gallery
- pk: 645
+ pk: 24
fields:
save_id: gallery23
name: Ex11_4
description: 'Digital Control (Author: K. M. Moudgalya), 11) Minimum Variance
Control, 11.4) 1st control problem by MacGregor'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="1000.0" title="stb_disc"><!--Xcos - 1.0 - scilab-5.5.2
@@ -27179,14 +29528,1299 @@
as="geometry" height="40.0" width="40.0" x="40.0" y="320.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-7476484f:145f8cd2a3c:-7be9" parent="-7476484f:145f8cd2a3c:-7be8"/></XcosDiagram>
media: gallery23.png
+ script_dump: '// MacGregor''s first control problem, discussed in Example 11.4
+ on page 213.
+
+ // 11.4
+
+ // Minimum variance control law design, given by Eq. 11.40 on page 413.
+
+ // 11.5
+
+
+ // function [S,dS,R,dR] = mv(A,dA,B,dB,C,dC,k,int)
+
+ // implements the minimum variance controller
+
+ // if int>=1, integrated noise is assumed; otherwise,
+
+ // it is not integrated noise
+
+
+ function [S,dS,R,dR] = mv(A,dA,B,dB,C,dC,k,int1)
+
+ zk = zeros(1,k+1); zk(k+1) = 1;
+
+ if int1>=1, [A,dA] = polmul([1 -1],1,A,dA); end
+
+ [Fk,dFk,Ek,dEk] = xdync(zk,k,A,dA,C,dC);
+
+
+ [Gk,dGk] = polmul(Ek,dEk,B,dB);
+
+ S = Fk; dS = dFk; R = Gk; dR = dGk;
+
+ endfunction;
+
+ // Calculation of closed loop transfer functions
+
+ // 11.6
+
+
+ // function [Nu,dNu,Du,dDu,Ny,dNy,Dy,dDy,yvar,uvar] = ...
+
+ // cl(A,dA,B,dB,C,dC,k,S,dS,R,dR,int)
+
+ // int>=1 means integrated noise and control law:
+
+ // delta u = - (S/R)y
+
+ // Evaluates the closed loop transfer function and
+
+ // variances of input and output
+
+
+ function [Nu,dNu,Du,dDu,Ny,dNy,Dy,dDy,yvar,uvar] = ...
+
+ cl(A,dA,B,dB,C,dC,k,S,dS,R,dR,int1)
+
+ [zk,dzk] = zpowk(k);
+
+
+ [BS,dBS] = polmul(B,dB,S,dS);
+
+ [zBS,dzBS] = polmul(zk,dzk,BS,dBS);
+
+ [RA,dRA] = polmul(R,dR,A,dA);
+
+ if int1>=1, [RA,dRA] = polmul(RA,dRA,[1 -1],1); end
+
+
+ [D,dD] = poladd(RA,dRA,zBS,dzBS);
+
+
+ [Ny,dNy] = polmul(C,dC,R,dR);
+
+ [Nu,dNu] = polmul(C,dC,S,dS);
+
+
+ [Nu,dNu,Du,dDu,uvar] = tfvar(Nu,dNu,D,dD);
+
+ [Ny,dNy,Dy,dDy,yvar] = tfvar(Ny,dNy,D,dD);
+
+
+ endfunction;
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1; end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+ function [C,degC] = poladd(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= cB | rA ~= rB
+
+ error(''poladd: Inconsistent dimensions'');
+
+ end
+
+
+ degC = max(degA,degB);
+
+ if degC >= degA
+
+ A = [A zeros(rA,(degC-degA)*cA)];
+
+ end
+
+ if degC >= degB
+
+ B = [B zeros(rB,(degC-degB)*cB)];
+
+ end
+
+ C = A+B;
+
+ endfunction;
+
+ // Cancellation of common factors and determination of covariance
+
+ // 11.7
+
+
+ // function [N,dN,D,dD,yvar] = tfvar(N,dN,D,dD)
+
+ // N and D polynomials in z^{-1} form; discrete case
+
+
+ function [N,dN,D,dD,yvar] = tfvar(N,dN,D,dD)
+
+
+ [N,dN,D,dD] = l2r(N,dN,D,dD);
+
+ N = N/D(1); D = D/D(1);
+
+ LN = length(N); LD = length(D);
+
+ D1 = D;
+
+ if LD<LN, D1 = [D zeros(1,LN-LD)]; dD1 = dD+LN-LD; end
+
+ H = tf(N,D1,1);//TS=1 (sampling time) has been taken constant in tfvar
+
+ yvar = covar_m(H,1);
+
+ endfunction;
+
+ // function [Rnum,Rnumdeg,Rden,Rdendeg] = l2r(N,degN,D,degD)
+
+ // given Numerator and Denominator polynomial matrices in left form,
+
+ // not necessarily coprime, finds right coprime factorisation.
+
+
+ function [Rnum,Rnumdeg,Rden,Rdendeg] = l2r(N,degN,D,degD)
+
+
+ [N,degN] = transp(N,degN);
+
+ [D,degD] = transp(D,degD);
+
+
+ [Rnum,Rnumdeg,Rden,Rdendeg] = left_prm(N,degN,D,degD);
+
+ [Rnum,Rnumdeg] = transp(Rnum,Rnumdeg);
+
+ [Rden,Rdendeg] = transp(Rden,Rdendeg);
+
+ endfunction;
+
+ // function [P,degP] = transp(Q,degQ)
+
+ // MATLAB FUNCTION transp TO TRANSPOSE
+
+ // A POLYNOMIAL MATRIX
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = transp(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ rP = cQ; cP = rQ; degP = degQ;
+
+ P = zeros(rP,(degP+1)*cP);
+
+ for i = 1:degP+1
+
+ P(:,(i-1)*cP+1:i*cP) = Q(:,(i-1)*cQ+1:i*cQ)'';
+
+ end
+
+
+ endfunction;
+
+ //User defined function
+
+ //Forms a transfer function
+
+ //Scilab: Co efficients are given in increasing power of variable
+
+ //Matlab: Co efficients are given in decreasing power of variable
+
+ //Hence co efficients are flipped here
+
+
+ //Input arguments: (1) Numerator co efficients(decreasing order)
+
+ //(2) Denominator co efficients
+
+ //(3) Variable to specify domain
+
+
+ // Updated (30-11-06)
+
+ // System is continuous => a is not passed
+
+ // System is discrete => a = -1
+
+ // System is discretized (sampled system) => a = Ts
+
+ // Uses syslin
+
+
+ function trfu = tf(num,den,a)
+
+ if argn(2) == 2
+
+ d = ''c'';
+
+ elseif a == -1
+
+ d = ''d'';
+
+ else
+
+ d = a
+
+ end;
+
+ num = clean(num);
+
+ den = clean(den);
+
+ num1 = poly(num(length(num):-1:1),''x'',''coeff'');
+
+ den1 = poly(den(length(den):-1:1),''x'',''coeff'');
+
+ trfu = syslin(d,num1,den1);
+
+ endfunction;
+
+
+
+
+ //User defined equivalent function to Matlab covar function
+
+ //For discrete time domain only
+
+ //Uses Lyapunov''s equation for computation
+
+ //W: noise intensity (scalar)
+
+ //Matlab result for unstable systems:
+
+ //Warning: Unstable models have infinite covariance
+
+
+ function P = covar_m(sys,W)
+
+ a = roots(sys(''den''));
+
+ b = length(a);
+
+ c = abs(a) > 1;
+
+ if b ~= 0 then
+
+ for i = 1:b
+
+ if c(i) == %t then
+
+ disp(''Warning: System being unstable has infinite covariance'');
+
+ P = %inf;
+
+ else
+
+ s = tf2ss(sys);
+
+ [A,B,C,D] = s(2:5);
+
+ //Sylvester and Lyapunov solver
+
+ task = 2; flag = [1 0]; tran = 1;
+
+ Q1 = -B*W*B'';
+
+ Q = linmeq(task,A,Q1,flag,tran)
+
+ P = C*Q*C'' + D*W*D'';
+
+ end;
+
+ end;
+
+ else
+
+ s = tf2ss(sys);
+
+ [A,B,C,D] = s(2:5);
+
+ //Sylvester and Lyapunov solver
+
+ task = 2; flag = [1 0]; tran = 1;
+
+ Q1 = -B*W*B'';
+
+ Q = linmeq(task,A,Q1,flag,tran)
+
+ P = C*Q*C'' + D*W*D'';
+
+ end;
+
+ endfunction;
+
+
+ //if d==0 | c==%f
+
+ // disp(''Calc'');
+
+ //else
+
+ // disp(''Unstable'');
+
+ //end;
+
+ // Above logic can also solve our purpose
+
+ // But it gives incorrect answer if roots are [1 -1 1] or
+
+ // [1 -1 -1] ....
+
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+ // MacGregor''s first control problem
+
+ A = [1 -1.4 0.45]; dA = 2; C = [1 -0.5]; dC = 1;
+
+ B = 0.5*[1 -0.9]; dB = 1; k = 1; int1 = 0;
+
+ [Sc,dSc,Rc,dRc] = mv(A,dA,B,dB,C,dC,k,int1);
+
+ [Nu,dNu,Du,dDu,Ny,dNy,Dy,dDy,yvar,uvar] = ...
+
+ cl(A,dA,B,dB,C,dC,k,Sc,dSc,Rc,dRc,int1);
+
+
+ // Simulation parameters for stb_disc.xcos
+
+ Tc = Sc; gamm = 1; [zk,dzk] = zpowk(k);
+
+ D = 1; N_var = 1; Ts = 1; st = 0;
+
+ t_init = 0; t_final = 1000;
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Rcp1,Rcp2] = cosfil_ip(1,Rc); // 1/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Bp,Ap] = cosfil_ip(B,A); // B/A
+
+ [zkp1,zkp2] = cosfil_ip(zk,1); // zk/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D'
- model: saveAPI.gallery
- pk: 646
+ pk: 25
fields:
save_id: gallery24
name: Ex7_6
description: 'Digital Control (Author: K. M. Moudgalya), 7) Structures and Specifications,
7.6) Verification of performance of lead controller on antenna system'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="20.0" title="g_s_cl2"><!--Xcos - 1.0 - scilab-5.5.2 -
@@ -29734,14 +33368,142 @@
as="geometry" height="40.0" width="40.0" x="460.0" y="360.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-75a601dc:14604d880d0:-7ffd" parent="-75a601dc:14604d880d0:-7ffc"/></XcosDiagram>
media: gallery24.png
+ script_dump: '// Verification of performance of lead controller on antenna system,
+ as discussed in Example 7.3.
+
+ // 7.6
+
+
+ // Continuous time antenna model
+
+ a = 0.1;
+
+ F = [0 1;0 -a]; g = [0; a]; c = [1 0]; d = 0;
+
+ Ga = syslin(''c'',F,g,c,d); [ds,num,den] = ss2tf(Ga);
+
+ Num = clean(num); Den = clean(den);
+
+ Ts = 0.2;
+
+ G = dscr(Ga,Ts);
+
+
+ // lead controller
+
+ beta1 = 0.8;
+
+ N = [1 -0.9802]*(1-beta1)/(1-0.9802); Rc = [1 -beta1];
+
+
+ // simulation parameters using g_s_cl2.cos
+
+ gamm = 1; Sc = 1; Tc = 1; C = 0; D = 1;
+
+ st = 1; st1 = 0;
+
+ t_init = 0; t_final = 20;
+
+
+ // u1: -4 to 11
+
+ // y1: 0 to 1.4
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Np,Rcp] = cosfil_ip(N,Rc); // N/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D'
- model: saveAPI.gallery
- pk: 647
+ pk: 26
fields:
save_id: gallery25
name: Ex7_7
description: 'Digital Control (Author: K. M. Moudgalya), 7) Structures and Specifications,
7.7) Illustration of system type'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="20.0" title="stb_disc"><!--Xcos - 1.0 - scilab-5.5.2 -
@@ -32157,14 +35919,1008 @@
as="geometry" height="40.0" width="40.0" x="40.0" y="320.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-7476484f:145f8cd2a3c:-7be9" parent="-7476484f:145f8cd2a3c:-7be8"/></XcosDiagram>
media: gallery25.png
+ script_dump: '// Illustration of system type, as explained in Example 7.10 on
+ page 275.
+
+ // 7.7
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1; end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+ // Solution to Aryabhatta''s identity arising in PID controller design, namely
+ Eq. 9.37 on page 363.
+
+ // 9.20
+
+
+ function [Rc,Sc] = pp_pid(B,A,k,phi,Delta)
+
+
+ // Setting up and solving Aryabhatta identity
+
+ dB = length(B) - 1; dA = length(A) - 1;
+
+ [zk,dzk] = zpowk(k);
+
+ [N,dN] = polmul(B,dB,zk,dzk);
+
+ dDelta = length(Delta)-1;
+
+ [D,dD] = polmul(A,dA,Delta,dDelta);
+
+ dphi = length(phi)-1;
+
+ [Sc,dSc,R,dR] = xdync(N,dN,D,dD,phi,dphi);
+
+ Rc = convol(R,Delta);
+
+ endfunction;
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // Plant
+
+ B = 1; A = [1 -1]; zk = [0 1]; Ts = 1; k = 1;
+
+ // Value of k absent in original code
+
+ // Specify closed loop characteristic polynomial
+
+ phi = [1 -0.5];
+
+
+ // Design the controller
+
+ reject_ramps = 1;
+
+ if reject_ramps == 1,
+
+ Delta = [1 -1]; // to reject ramps another Delta
+
+ else
+
+ Delta = 1; // steps can be rejected by plant itself
+
+ end
+
+ [Rc,Sc] = pp_pid(B,A,k,phi,Delta);
+
+
+ // parameters for simulation using stb_disc.mdl
+
+ Tc = Sc; gamm = 1; N = 1;
+
+ C = 0; D = 1; N_var = 0;
+
+ st = 1; t_init = 0; t_final = 20;
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Rcp1,Rcp2] = cosfil_ip(1,Rc); // 1/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Bp,Ap] = cosfil_ip(B,A); // B/A
+
+ [zkp1,zkp2] = cosfil_ip(zk,1); // zk/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D
+
+
+ // Give appropriate path
+
+ //xcos(''stb_disc.xcos'');'
- model: saveAPI.gallery
- pk: 648
+ pk: 27
fields:
save_id: gallery26
name: Ex9_10
description: 'Digital Control (Author: K. M. Moudgalya), 9) Pole Placement Controllers,
9.10) Pole placement controller IBM Lotus Domino server'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="40.0" title="Ex9_10"><!--Xcos - 1.0 - scilab-5.5.2 - 20150331
@@ -34512,14 +39268,1101 @@
as="defaultParent" id="-2f864670:16fc63faf34:-7bc7" parent="-2f864670:16fc63faf34:-7bc6"/><mxPoint
as="origin" x="-80.0"/></XcosDiagram>
media: gallery26.png
+ script_dump: '// Pole placement controller IBM Lotus Domino server, discussed
+ in Example 9.9 on page 341.
+
+ // 9.10
+
+ // Calculation of desired closed loop characteristic polynomial, as discussed
+ in Sec. 7.7.
+
+ // 9.4
+
+
+ // function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ // Based on transient requirements,
+
+ // calculates closed loop characteristic polynomial
+
+
+ function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ Nr = rise/Ts; omega = %pi/2/Nr; rho = epsilon^(omega/%pi);
+
+ phi = [1 -2*rho*cos(omega) rho^2]; dphi = length(phi)-1;
+
+ endfunction;
+
+ // Pole placement controller using internal model principle, as discussed in
+ Sec. 9.4.
+
+ // 9.8
+
+
+ // function [Rc,Sc,Tc,gamma,phit] = pp_im(B,A,k,phi,Delta)
+
+ // Calculates 2-DOF pole placement controller.
+
+
+ function [Rc,Sc,Tc,gamm] = pp_im(B,A,k,phi,Delta)
+
+
+ // Setting up and solving Aryabhatta identity
+
+ [Ag,Ab] = polsplit3(A); dAb = length(Ab) - 1;
+
+ [Bg,Bb] = polsplit3(B); dBb = length(Bb) - 1;
+
+
+ [zk,dzk] = zpowk(k);
+
+
+ [N,dN] = polmul(Bb,dBb,zk,dzk);
+
+ dDelta = length(Delta)-1;
+
+ [D,dD] = polmul(Ab,dAb,Delta,dDelta);
+
+ dphi = length(phi)-1;
+
+
+ [S1,dS1,R1,dR1] = xdync(N,dN,D,dD,phi,dphi);
+
+
+ // Determination of control law
+
+ Rc = convol(Bg,convol(R1,Delta)); Sc = convol(Ag,S1);
+
+ Tc = Ag; gamm = sum(phi)/sum(Bb);
+
+ endfunction;
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // Procedure to split a polynomial into good and bad factors, as discussed in
+ Sec. 9.5. The factors that have roots outside unit circle or with negative real
+ parts are defined as bad.
+
+ // 9.12
+
+
+ // function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ // Splits a scalar polynomial of z^{-1} into good and bad
+
+ // factors. Input is a polynomial in increasing degree of
+
+ // z^{-1}. Optional input is a, where a <= 1.
+
+ // Factors that have roots outside a circle of radius a or
+
+ // with negative roots will be called bad and the rest
+
+ // good. If a is not specified, it will be assumed as 1.
+
+
+ function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ if argn(2) == 1, a = 1; end
+
+ if a>1 error(''good polynomial also is unstable''); end
+
+ fac1 = poly(fac(length(fac):-1:1),''z'',''coeff'');
+
+ rts = roots(fac1);
+
+ rts = rts(length(rts):-1:1);
+
+
+ // extract good and bad roots
+
+ badindex = mtlb_find((abs(rts)>=a-1.0e-5)|(real(rts)<-0.05));
+
+ badpoly = coeff(poly(rts(badindex),''z''));
+
+ goodindex = mtlb_find((abs(rts)<a-1.0e-5)&(real(rts)>=-0.05));
+
+ goodpoly = coeff(poly(rts(goodindex),''z''));
+
+
+ // scale by equating the largest terms
+
+ [m,index] = max(abs(fac));
+
+ goodbad = convol(goodpoly,badpoly);
+
+ goodbad = goodbad(length(goodbad):-1:1);
+
+ factor1 = fac(index)/goodbad(index);
+
+ goodpoly = goodpoly * factor1;
+
+ goodpoly = goodpoly(length(goodpoly):-1:1);
+
+ badpoly = badpoly(length(badpoly):-1:1);
+
+ endfunction;
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1; end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+ // Control of IBM lotus domino server
+
+ // Transfer function
+
+ B = 0.47; A = [1 -0.43]; k = 1;
+
+ [zk,dzk] = zpowk(k);
+
+
+ // Transient specifications
+
+ rise = 10; epsilon = 0.01; Ts = 1;
+
+ phi = desired(Ts,rise,epsilon);
+
+
+ // Controller design
+
+ Delta = [1 -1]; // internal model of step used
+
+ [Rc,Sc,Tc,gamm] = pp_im(B,A,k,phi,Delta);
+
+
+ // Simulation parameters for stb_disc.xcos
+
+ st = 1; // desired change
+
+ t_init = 0; // simulation start time
+
+ t_final = 40; // simulation end time
+
+ C = 0; D = 1; N_var = 0;
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Rcp1,Rcp2] = cosfil_ip(1,Rc); // 1/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Bp,Ap] = cosfil_ip(B,A); // B/A
+
+ [zkp1,zkp2] = cosfil_ip(zk,1); // zk/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D'
- model: saveAPI.gallery
- pk: 649
+ pk: 28
fields:
save_id: gallery27
name: Ex9_11
description: 'Digital Control (Author: K. M. Moudgalya), 9) Pole Placement Controllers,
9.11) Pole placement controller for motor problem'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="Untitled - 10:43:53 AM"><!--Xcos - 1.0 -
@@ -36812,14 +42655,1141 @@
as="points" scilabClass=""><mxPoint x="520.0" y="450.0"/></Array></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="-2f864670:16fc63faf34:-759a" parent="-2f864670:16fc63faf34:-7599"/></XcosDiagram>
media: gallery27.png
+ script_dump: '// Pole placement controller for motor problem, discussed in Example
+ 9.10 on page 343.
+
+ // 9.11
+
+
+ // Calculation of desired closed loop characteristic polynomial, as discussed
+ in Sec. 7.7.
+
+ // 9.4
+
+
+ // function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ // Based on transient requirements,
+
+ // calculates closed loop characteristic polynomial
+
+
+ function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ Nr = rise/Ts; omega = %pi/2/Nr; rho = epsilon^(omega/%pi);
+
+ phi = [1 -2*rho*cos(omega) rho^2]; dphi = length(phi)-1;
+
+ endfunction;
+
+ // Pole placement controller using internal model principle, as discussed in
+ Sec. 9.4.
+
+ // 9.8
+
+
+ // function [Rc,Sc,Tc,gamma,phit] = pp_im(B,A,k,phi,Delta)
+
+ // Calculates 2-DOF pole placement controller.
+
+
+ function [Rc,Sc,Tc,gamm] = pp_im(B,A,k,phi,Delta)
+
+
+ // Setting up and solving Aryabhatta identity
+
+ [Ag,Ab] = polsplit3(A); dAb = length(Ab) - 1;
+
+ [Bg,Bb] = polsplit3(B); dBb = length(Bb) - 1;
+
+
+ [zk,dzk] = zpowk(k);
+
+
+ [N,dN] = polmul(Bb,dBb,zk,dzk);
+
+ dDelta = length(Delta)-1;
+
+ [D,dD] = polmul(Ab,dAb,Delta,dDelta);
+
+ dphi = length(phi)-1;
+
+
+ [S1,dS1,R1,dR1] = xdync(N,dN,D,dD,phi,dphi);
+
+
+ // Determination of control law
+
+ Rc = convol(Bg,convol(R1,Delta)); Sc = convol(Ag,S1);
+
+ Tc = Ag; gamm = sum(phi)/sum(Bb);
+
+ endfunction;
+
+ // Discretization of continuous transfer function. The result is numerator and
+ denominator in powers of z^{-1} and the delay term k.
+
+ // 9.2
+
+ // function [B,A,k] = myc2d(G,Ts)
+
+ // Produces numerator and denominator of discrete transfer
+
+ // function in powers of z^{-1}
+
+ // G is continuous transfer function; time delays are not allowed
+
+ // Ts is the sampling time, all in consistent time units
+
+
+ function [B,A,k] = myc2d(G,Ts)
+
+ H = ss2tf(dscr(G,Ts));
+
+ num1 = coeff(H(''num''));
+
+ den1 = coeff(H(''den''));//-------------
+
+ A = den1(length(den1):-1:1);
+
+ num2 = num1(length(num1):-1:1); //flip
+
+ nonzero = find(num1);
+
+ first_nz = nonzero(1);
+
+ B = num2(first_nz:length(num2)); //-------------
+
+ k = length(den1) - length(num1);
+
+ endfunction
+
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // Procedure to split a polynomial into good and bad factors, as discussed in
+ Sec. 9.5. The factors that have roots outside unit circle or with negative real
+ parts are defined as bad.
+
+ // 9.12
+
+
+ // function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ // Splits a scalar polynomial of z^{-1} into good and bad
+
+ // factors. Input is a polynomial in increasing degree of
+
+ // z^{-1}. Optional input is a, where a <= 1.
+
+ // Factors that have roots outside a circle of radius a or
+
+ // with negative roots will be called bad and the rest
+
+ // good. If a is not specified, it will be assumed as 1.
+
+
+ function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ if argn(2) == 1, a = 1; end
+
+ if a>1 error(''good polynomial also is unstable''); end
+
+ fac1 = poly(fac(length(fac):-1:1),''z'',''coeff'');
+
+ rts = roots(fac1);
+
+ rts = rts(length(rts):-1:1);
+
+
+ // extract good and bad roots
+
+ badindex = mtlb_find((abs(rts)>=a-1.0e-5)|(real(rts)<-0.05));
+
+ badpoly = coeff(poly(rts(badindex),''z''));
+
+ goodindex = mtlb_find((abs(rts)<a-1.0e-5)&(real(rts)>=-0.05));
+
+ goodpoly = coeff(poly(rts(goodindex),''z''));
+
+
+ // scale by equating the largest terms
+
+ [m,index] = max(abs(fac));
+
+ goodbad = convol(goodpoly,badpoly);
+
+ goodbad = goodbad(length(goodbad):-1:1);
+
+ factor1 = fac(index)/goodbad(index);
+
+ goodpoly = goodpoly * factor1;
+
+ goodpoly = goodpoly(length(goodpoly):-1:1);
+
+ badpoly = badpoly(length(badpoly):-1:1);
+
+ endfunction;
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1; end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+ // Motor control problem
+
+ // Transfer function
+
+ a1 = [-1 0; 1 0]; b1 = [1; 0]; c1 = [0 1]; d1 = 0;
+
+ G = syslin(''c'',a1,b1,c1,d1); Ts = 0.25;
+
+ [B,A,k] = myc2d(G,Ts);
+
+
+ // Transient specifications
+
+ rise = 3; epsilon = 0.05;
+
+ phi = desired(Ts,rise,epsilon);
+
+
+ // Controller design
+
+ Delta = 1; // No internal model of step used
+
+ [Rc,Sc,Tc,gamm] = pp_im(B,A,k,phi,Delta);
+
+
+ // simulation parameters for c_ss_cl.xcos
+
+ st = 1; //desired change in position
+
+ t_init = 0; //simulation start time
+
+ t_final = 10; //simulation end time
+
+ xInitial = [0 0]; //initial conditions
+
+ N = 1; C = 0; D = 1; N_var = 0;
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Np,Rcp] = cosfil_ip(N,Rc); // 1/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D'
- model: saveAPI.gallery
- pk: 650
+ pk: 29
fields:
save_id: gallery28
name: Ex9_14
description: 'Digital Control (Author: K. M. Moudgalya), 9) Pole Placement Controllers,
9.14) Controller design'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="1.5" title="Ex9_14"><!--Xcos - 1.0 - scilab-5.5.2 - 20150331
@@ -39360,14 +46330,1251 @@
as="geometry" height="40.0" width="40.0" x="680.0" y="400.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-2f864670:16fc63faf34:-72c4" parent="-2f864670:16fc63faf34:-72c3"/></XcosDiagram>
media: gallery28.png
+ script_dump: '// Controller design for the case study presented in Example 9.12
+ on page 347.
+
+ // 9.14
+
+
+ //User defined function
+
+ //Forms a transfer function
+
+ //Scilab: Co efficients are given in increasing power of variable
+
+ //Matlab: Co efficients are given in decreasing power of variable
+
+ //Hence co efficients are flipped here
+
+
+ //Input arguments: (1) Numerator co efficients(decreasing order)
+
+ //(2) Denominator co efficients
+
+ //(3) Variable to specify domain
+
+
+ // Updated (30-11-06)
+
+ // System is continuous => a is not passed
+
+ // System is discrete => a = -1
+
+ // System is discretized (sampled system) => a = Ts
+
+ // Uses syslin
+
+
+ function trfu = tf(num,den,a)
+
+ if argn(2) == 2
+
+ d = ''c'';
+
+ elseif a == -1
+
+ d = ''d'';
+
+ else
+
+ d = a
+
+ end;
+
+ num = clean(num);
+
+ den = clean(den);
+
+ num1 = poly(num(length(num):-1:1),''x'',''coeff'');
+
+ den1 = poly(den(length(den):-1:1),''x'',''coeff'');
+
+ trfu = syslin(d,num1,den1);
+
+ endfunction;
+
+
+ // Calculation of desired closed loop characteristic polynomial, as discussed
+ in Sec. 7.7.
+
+ // 9.4
+
+
+ // function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ // Based on transient requirements,
+
+ // calculates closed loop characteristic polynomial
+
+
+ function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ Nr = rise/Ts; omega = %pi/2/Nr; rho = epsilon^(omega/%pi);
+
+ phi = [1 -2*rho*cos(omega) rho^2]; dphi = length(phi)-1;
+
+ endfunction;
+
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+
+ // Discretization of continuous transfer function. The result is numerator and
+ denominator in powers of z^{-1} and the delay term k.
+
+ // 9.2
+
+ // function [B,A,k] = myc2d(G,Ts)
+
+ // Produces numerator and denominator of discrete transfer
+
+ // function in powers of z^{-1}
+
+ // G is continuous transfer function; time delays are not allowed
+
+ // Ts is the sampling time, all in consistent time units
+
+
+ function [B,A,k] = myc2d(G,Ts)
+
+ H = ss2tf(dscr(G,Ts));
+
+ num1 = coeff(H(''num''));
+
+ den1 = coeff(H(''den''));//-------------
+
+ A = den1(length(den1):-1:1);
+
+ num2 = num1(length(num1):-1:1); //flip
+
+ nonzero = find(num1);
+
+ first_nz = nonzero(1);
+
+ B = num2(first_nz:length(num2)); //-------------
+
+ k = length(den1) - length(num1);
+
+ endfunction
+
+
+ // Procedure to split a polynomial into good and bad factors, as discussed in
+ Sec. 9.5. The factors that have roots outside unit circle or with negative real
+ parts are defined as bad.
+
+ // 9.12
+
+
+ // function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ // Splits a scalar polynomial of z^{-1} into good and bad
+
+ // factors. Input is a polynomial in increasing degree of
+
+ // z^{-1}. Optional input is a, where a <= 1.
+
+ // Factors that have roots outside a circle of radius a or
+
+ // with negative roots will be called bad and the rest
+
+ // good. If a is not specified, it will be assumed as 1.
+
+
+ function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ if argn(2) == 1, a = 1; end
+
+ if a>1 error(''good polynomial also is unstable''); end
+
+ fac1 = poly(fac(length(fac):-1:1),''z'',''coeff'');
+
+ rts = roots(fac1);
+
+ rts = rts(length(rts):-1:1);
+
+
+ // extract good and bad roots
+
+ badindex = mtlb_find((abs(rts)>=a-1.0e-5)|(real(rts)<-0.05));
+
+ badpoly = coeff(poly(rts(badindex),''z''));
+
+ goodindex = mtlb_find((abs(rts)<a-1.0e-5)&(real(rts)>=-0.05));
+
+ goodpoly = coeff(poly(rts(goodindex),''z''));
+
+
+ // scale by equating the largest terms
+
+ [m,index] = max(abs(fac));
+
+ goodbad = convol(goodpoly,badpoly);
+
+ goodbad = goodbad(length(goodbad):-1:1);
+
+ factor1 = fac(index)/goodbad(index);
+
+ goodpoly = goodpoly * factor1;
+
+ goodpoly = goodpoly(length(goodpoly):-1:1);
+
+ badpoly = badpoly(length(badpoly):-1:1);
+
+ endfunction;
+
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1;
+
+ end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // Pole placement controller without intra sample oscillations, as discussed
+ in Sec. 9.5.
+
+ // 9.13
+
+
+ // function [Rc,Sc,Tc,gamma,phit] = pp_im2(B,A,k,phi,Delta,a)
+
+ // 2-DOF PP controller with internal model of Delta and without
+
+ // hidden oscillations
+
+
+ function [Rc,Sc,Tc,gamm,phit] = pp_im2(B,A,k,phi,Delta,a)
+
+
+ if argn(2) == 5, a = 1; end
+
+ dphi = length(phi)-1;
+
+
+ // Setting up and solving Aryabhatta identity
+
+ [Ag,Ab] = polsplit3(A,a); dAb = length(Ab) - 1;
+
+ [Bg,Bb] = polsplit3(B,a); dBb = length(Bb) - 1;
+
+
+ [zk,dzk] = zpowk(k);
+
+
+ [N,dN] = polmul(Bb,dBb,zk,dzk);
+
+ dDelta = length(Delta)-1;
+
+ [D,dD] = polmul(Ab,dAb,Delta,dDelta);
+
+
+ [S1,dS1,R1,dR1] = xdync(N,dN,D,dD,phi,dphi);
+
+
+ // Determination of control law
+
+ Rc = convol(Bg,convol(R1,Delta)); Sc = convol(Ag,S1);
+
+ Tc = Ag; gamm = sum(phi)/sum(Bb);
+
+
+ // Total characteristic polynomial
+
+ phit = convol(phi,convol(Ag,Bg));
+
+ endfunction;
+
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+
+ num = 200;
+
+ den = convol([0.05 1],[0.05 1]);
+
+ den = convol([10 1],den);
+
+ G = tf(num,den); Ts = 0.025;
+
+ num = G(''num''); den = G(''den'');
+
+ // iodel = 0;
+
+ [B,A,k] = myc2d(G,Ts);
+
+ [zk,dzk] = zpowk(k); //int1 = 0;
+
+
+ // Transient specifications
+
+ a = 0.9; rise = 0.24; epsilon = 0.05;
+
+ phi = desired(Ts,rise,epsilon);
+
+
+ // Controller design
+
+ Delta = [1 -1]; // internal model of step is present
+
+ [Rc,Sc,Tc,gamm] = pp_im2(B,A,k,phi,Delta,a);
+
+
+ // margin calculation
+
+ Lnum = convol(Sc,convol(B,zk));
+
+ Lden = convol(Rc,A);
+
+ L = tf(Lnum,Lden,Ts);
+
+ // Gm = g_margin(L); //---- Does not match --------------- (in dB)
+
+ Pm = p_margin(L); //---- Convergence problem --------------- (in degree)
+
+
+ num1 = 100; den1 = [10 1];
+
+ Gd = tf(num1,den1); //-------
+
+ [C,D,k1] = myc2d(Gd,Ts);
+
+ [zk,dzk] = zpowk(k);
+
+ C = convol(C,zk);
+
+
+ // simulation parameters g_s_cl2.xcos ------------
+
+ N = 1;
+
+ st = 1; // desired change in setpoint
+
+ st1 = 0; // magnitude of disturbance
+
+ t_init = 0; // simulation start time
+
+ t_final = 1.5; // simulation end time
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Np,Rcp] = cosfil_ip(N,Rc); // N/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D'
- model: saveAPI.gallery
- pk: 651
+ pk: 30
fields:
save_id: gallery29
name: Ex9_15_1
description: 'Digital Control (Author: K. M. Moudgalya), 9) Pole Placement Controllers,
9.15) Evaluation of continuous time controller'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0" title="Ex9_15_1"><!--Xcos - 1.0 - scilab-5.5.2 -
@@ -41866,14 +50073,308 @@
as="geometry" height="40.0" width="40.0" x="760.0" y="420.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-2f864670:16fc63faf34:-6b2d" parent="-2f864670:16fc63faf34:-6b2c"/></XcosDiagram>
media: gallery29.png
+ script_dump: '// Evaluation of continuous time controller for the case study presented
+ in Example 9.13 on page 349.
+
+ // 9.15
+
+
+ //User defined function
+
+ //Forms a transfer function
+
+ //Scilab: Co efficients are given in increasing power of variable
+
+ //Matlab: Co efficients are given in decreasing power of variable
+
+ //Hence co efficients are flipped here
+
+
+ //Input arguments: (1) Numerator co efficients(decreasing order)
+
+ //(2) Denominator co efficients
+
+ //(3) Variable to specify domain
+
+
+ // Updated (30-11-06)
+
+ // System is continuous => a is not passed
+
+ // System is discrete => a = -1
+
+ // System is discretized (sampled system) => a = Ts
+
+ // Uses syslin
+
+
+ function trfu = tf(num,den,a)
+
+ if argn(2) == 2
+
+ d = ''c'';
+
+ elseif a == -1
+
+ d = ''d'';
+
+ else
+
+ d = a
+
+ end;
+
+ num = clean(num);
+
+ den = clean(den);
+
+ num1 = poly(num(length(num):-1:1),''x'',''coeff'');
+
+ den1 = poly(den(length(den):-1:1),''x'',''coeff'');
+
+ trfu = syslin(d,num1,den1);
+
+ endfunction;
+
+
+ // Discretization of continuous transfer function. The result is numerator and
+ denominator in powers of z^{-1} and the delay term k.
+
+ // 9.2
+
+ // function [B,A,k] = myc2d(G,Ts)
+
+ // Produces numerator and denominator of discrete transfer
+
+ // function in powers of z^{-1}
+
+ // G is continuous transfer function; time delays are not allowed
+
+ // Ts is the sampling time, all in consistent time units
+
+
+ function [B,A,k] = myc2d(G,Ts)
+
+ H = ss2tf(dscr(G,Ts));
+
+ num1 = coeff(H(''num''));
+
+ den1 = coeff(H(''den''));//-------------
+
+ A = den1(length(den1):-1:1);
+
+ num2 = num1(length(num1):-1:1); //flip
+
+ nonzero = find(num1);
+
+ first_nz = nonzero(1);
+
+ B = num2(first_nz:length(num2)); //-------------
+
+ k = length(den1) - length(num1);
+
+ endfunction
+
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+
+ num = 200;
+
+ den = convol([0.05 1],[0.05 1]);
+
+ den = convol([10 1],den);
+
+ G = tf(num,den); Ts = 0.005;
+
+ [B,A,k] = myc2d(G,Ts);
+
+ [zk,dzk] = zpowk(k); //int = 0;
+
+
+ // Sigurd''s feedback controller''
+
+ numb = 0.5*convol([1 2],[0.05 1]);
+
+ denb = convol([1 0],[0.005 1]);
+
+ Gb = tf(numb,denb);
+
+ [Sb,Rb,kb] = myc2d(Gb,Ts);
+
+ [zkb,dzkb] = zpowk(kb);
+
+ Sb = convol(Sb,zkb);
+
+
+ // Sigurd''s feed forward controller''
+
+ numf = [0.5 1];
+
+ denf = convol([0.65 1],[0.03 1]);
+
+ Gf = tf(numf,denf);
+
+ [Sf,Rf,kf] = myc2d(Gf,Ts);
+
+ [zkf,dzkf] = zpowk(kf);
+
+ Sf = convol(Sf,zkf);
+
+
+ // Margins
+
+ simp_mode(%f);
+
+ L = G*Gb;
+
+ // Gm = g_margin(L); // ------
+
+ Pm = p_margin(L); // ------
+
+ Lnum = convol(Sb,convol(zk,B));
+
+ Lden = convol(Rb,A);
+
+ L = tf(Lnum,Lden,Ts);
+
+ // DGm = g_margin(L); // ------
+
+ DPm = p_margin(L); // ------
+
+
+ // Noise
+
+ num1 = 100; den1 = [10 1];
+
+
+ // simulation parameters for
+
+ // entirely continuous simulation: g_s_cl3.xcos
+
+ // hybrid simulation: g_s_cl6.xcos
+
+ st = 1; // desired change in setpoint
+
+ st1 = 0;
+
+ t_init = 0; // simulation start time
+
+ t_final = 5; // simulation end time
+
+
+ num = polyno(num,''s''); den = polyno(den,''s'');
+
+ Numb = polyno(numb,''s''); Denb = polyno(denb,''s'');
+
+ Numf = polyno(numf,''s''); Denf = polyno(denf,''s'');
+
+ Num1 = polyno(num1,''s''); Den1 = polyno(den1,''s'');
+
+
+ [Sbp,Rbp] = cosfil_ip(Sb,Rb);
+
+ [Sfp,Rfp] = cosfil_ip(Sf,Rf);'
- model: saveAPI.gallery
- pk: 652
+ pk: 31
fields:
save_id: gallery30
name: Ex9_15_2
description: 'Digital Control (Author: K. M. Moudgalya), 9) Pole Placement Controllers,
9.15) Evaluation of continuous time controller'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0" title="Ex9_15_2"><!--Xcos - 1.0 - scilab-5.5.2 -
@@ -44481,14 +52982,308 @@
as="defaultParent" id="-2f864670:16fc63faf34:-6546" parent="-2f864670:16fc63faf34:-6545"/><mxPoint
as="origin" y="-10.0"/></XcosDiagram>
media: gallery30.png
+ script_dump: '// Evaluation of continuous time controller for the case study presented
+ in Example 9.13 on page 349.
+
+ // 9.15
+
+
+ //User defined function
+
+ //Forms a transfer function
+
+ //Scilab: Co efficients are given in increasing power of variable
+
+ //Matlab: Co efficients are given in decreasing power of variable
+
+ //Hence co efficients are flipped here
+
+
+ //Input arguments: (1) Numerator co efficients(decreasing order)
+
+ //(2) Denominator co efficients
+
+ //(3) Variable to specify domain
+
+
+ // Updated (30-11-06)
+
+ // System is continuous => a is not passed
+
+ // System is discrete => a = -1
+
+ // System is discretized (sampled system) => a = Ts
+
+ // Uses syslin
+
+
+ function trfu = tf(num,den,a)
+
+ if argn(2) == 2
+
+ d = ''c'';
+
+ elseif a == -1
+
+ d = ''d'';
+
+ else
+
+ d = a
+
+ end;
+
+ num = clean(num);
+
+ den = clean(den);
+
+ num1 = poly(num(length(num):-1:1),''x'',''coeff'');
+
+ den1 = poly(den(length(den):-1:1),''x'',''coeff'');
+
+ trfu = syslin(d,num1,den1);
+
+ endfunction;
+
+
+ // Discretization of continuous transfer function. The result is numerator and
+ denominator in powers of z^{-1} and the delay term k.
+
+ // 9.2
+
+ // function [B,A,k] = myc2d(G,Ts)
+
+ // Produces numerator and denominator of discrete transfer
+
+ // function in powers of z^{-1}
+
+ // G is continuous transfer function; time delays are not allowed
+
+ // Ts is the sampling time, all in consistent time units
+
+
+ function [B,A,k] = myc2d(G,Ts)
+
+ H = ss2tf(dscr(G,Ts));
+
+ num1 = coeff(H(''num''));
+
+ den1 = coeff(H(''den''));//-------------
+
+ A = den1(length(den1):-1:1);
+
+ num2 = num1(length(num1):-1:1); //flip
+
+ nonzero = find(num1);
+
+ first_nz = nonzero(1);
+
+ B = num2(first_nz:length(num2)); //-------------
+
+ k = length(den1) - length(num1);
+
+ endfunction
+
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+
+ num = 200;
+
+ den = convol([0.05 1],[0.05 1]);
+
+ den = convol([10 1],den);
+
+ G = tf(num,den); Ts = 0.005;
+
+ [B,A,k] = myc2d(G,Ts);
+
+ [zk,dzk] = zpowk(k); //int = 0;
+
+
+ // Sigurd''s feedback controller''
+
+ numb = 0.5*convol([1 2],[0.05 1]);
+
+ denb = convol([1 0],[0.005 1]);
+
+ Gb = tf(numb,denb);
+
+ [Sb,Rb,kb] = myc2d(Gb,Ts);
+
+ [zkb,dzkb] = zpowk(kb);
+
+ Sb = convol(Sb,zkb);
+
+
+ // Sigurd''s feed forward controller''
+
+ numf = [0.5 1];
+
+ denf = convol([0.65 1],[0.03 1]);
+
+ Gf = tf(numf,denf);
+
+ [Sf,Rf,kf] = myc2d(Gf,Ts);
+
+ [zkf,dzkf] = zpowk(kf);
+
+ Sf = convol(Sf,zkf);
+
+
+ // Margins
+
+ simp_mode(%f);
+
+ L = G*Gb;
+
+ // Gm = g_margin(L); // ------
+
+ Pm = p_margin(L); // ------
+
+ Lnum = convol(Sb,convol(zk,B));
+
+ Lden = convol(Rb,A);
+
+ L = tf(Lnum,Lden,Ts);
+
+ // DGm = g_margin(L); // ------
+
+ DPm = p_margin(L); // ------
+
+
+ // Noise
+
+ num1 = 100; den1 = [10 1];
+
+
+ // simulation parameters for
+
+ // entirely continuous simulation: g_s_cl3.xcos
+
+ // hybrid simulation: g_s_cl6.xcos
+
+ st = 1; // desired change in setpoint
+
+ st1 = 0;
+
+ t_init = 0; // simulation start time
+
+ t_final = 5; // simulation end time
+
+
+ num = polyno(num,''s''); den = polyno(den,''s'');
+
+ Numb = polyno(numb,''s''); Denb = polyno(denb,''s'');
+
+ Numf = polyno(numf,''s''); Denf = polyno(denf,''s'');
+
+ Num1 = polyno(num1,''s''); Den1 = polyno(den1,''s'');
+
+
+ [Sbp,Rbp] = cosfil_ip(Sb,Rb);
+
+ [Sfp,Rfp] = cosfil_ip(Sf,Rf);'
- model: saveAPI.gallery
- pk: 653
+ pk: 32
fields:
save_id: gallery31
name: Ex9_16
description: 'Digital Control (Author: K. M. Moudgalya), 9) Pole Placement Controllers,
9.16) System type with 2 DOF controller'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="20.0" title="Ex9_16"><!--Xcos - 1.0 - scilab-5.5.2 - 20150331
@@ -46908,14 +55703,1068 @@
as="defaultParent" id="-2f864670:16fc63faf34:-5f92" parent="-2f864670:16fc63faf34:-5f91"/><mxPoint
as="origin" x="-350.0"/></XcosDiagram>
media: gallery31.png
+ script_dump: '// System type with 2-DOF controller. It is used to arrive at the
+ results Example 9.14.
+
+ // 9.16
+
+ // Procedure to split a polynomial into good and bad factors, as discussed in
+ Sec. 9.5. The factors that have roots outside unit circle or with negative real
+ parts are defined as bad.
+
+ // 9.12
+
+
+ // function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ // Splits a scalar polynomial of z^{-1} into good and bad
+
+ // factors. Input is a polynomial in increasing degree of
+
+ // z^{-1}. Optional input is a, where a <= 1.
+
+ // Factors that have roots outside a circle of radius a or
+
+ // with negative roots will be called bad and the rest
+
+ // good. If a is not specified, it will be assumed as 1.
+
+
+ function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ if argn(2) == 1, a = 1; end
+
+ if a>1 error(''good polynomial also is unstable''); end
+
+ fac1 = poly(fac(length(fac):-1:1),''z'',''coeff'');
+
+ rts = roots(fac1);
+
+ rts = rts(length(rts):-1:1);
+
+
+ // extract good and bad roots
+
+ badindex = mtlb_find((abs(rts)>=a-1.0e-5)|(real(rts)<-0.05));
+
+ badpoly = coeff(poly(rts(badindex),''z''));
+
+ goodindex = mtlb_find((abs(rts)<a-1.0e-5)&(real(rts)>=-0.05));
+
+ goodpoly = coeff(poly(rts(goodindex),''z''));
+
+
+ // scale by equating the largest terms
+
+ [m,index] = max(abs(fac));
+
+ goodbad = convol(goodpoly,badpoly);
+
+ goodbad = goodbad(length(goodbad):-1:1);
+
+ factor1 = fac(index)/goodbad(index);
+
+ goodpoly = goodpoly * factor1;
+
+ goodpoly = goodpoly(length(goodpoly):-1:1);
+
+ badpoly = badpoly(length(badpoly):-1:1);
+
+ endfunction;
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+ // Pole placement controller using internal model principle, as discussed in
+ Sec. 9.4.
+
+ // 9.8
+
+
+ // function [Rc,Sc,Tc,gamma,phit] = pp_im(B,A,k,phi,Delta)
+
+ // Calculates 2-DOF pole placement controller.
+
+
+ function [Rc,Sc,Tc,gamm] = pp_im(B,A,k,phi,Delta)
+
+
+ // Setting up and solving Aryabhatta identity
+
+ [Ag,Ab] = polsplit3(A); dAb = length(Ab) - 1;
+
+ [Bg,Bb] = polsplit3(B); dBb = length(Bb) - 1;
+
+
+ [zk,dzk] = zpowk(k);
+
+
+ [N,dN] = polmul(Bb,dBb,zk,dzk);
+
+ dDelta = length(Delta)-1;
+
+ [D,dD] = polmul(Ab,dAb,Delta,dDelta);
+
+ dphi = length(phi)-1;
+
+
+ [S1,dS1,R1,dR1] = xdync(N,dN,D,dD,phi,dphi);
+
+
+ // Determination of control law
+
+ Rc = convol(Bg,convol(R1,Delta)); Sc = convol(Ag,S1);
+
+ Tc = Ag; gamm = sum(phi)/sum(Bb);
+
+ endfunction;
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1; end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+ B = 1; A = [1 -1]; k = 1; zk = zpowk(k); Ts = 1;
+
+ phi = [1 -0.5];
+
+
+ Delta = 1; // Choice of internal model of step
+
+ [Rc,Sc,Tc,gamm] = pp_im(B,A,k,phi,Delta);
+
+
+ // simulation parameters for stb_disc.xcos
+
+ st = 1; // desired step change
+
+ t_init = 0; // simulation start time
+
+ t_final = 20; // simulation end time
+
+ xInitial = [0 0];
+
+ C = 0; D = 1; N_var = 0;
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Rcp1,Rcp2] = cosfil_ip(1,Rc); // 1/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Bp,Ap] = cosfil_ip(B,A); // B/A
+
+ [zkp1,zkp2] = cosfil_ip(zk,1); // zk/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D'
- model: saveAPI.gallery
- pk: 654
+ pk: 33
fields:
save_id: gallery32
name: Ex9_17
description: 'Digital Control (Author: K. M. Moudgalya), 9) Pole Placement Controllers,
9.17) Illustrating the benefit of cancellation'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="20.0" title="Ex9_17"><!--Xcos - 1.0 - scilab-5.5.2 - 20150331
@@ -49329,14 +59178,1056 @@
as="defaultParent" id="-2f864670:16fc63faf34:-5c8f" parent="-2f864670:16fc63faf34:-5c8e"/><mxPoint
as="origin" x="-60.0"/></XcosDiagram>
media: gallery32.png
+ script_dump: '// Illustrating the benefit of cancellation. It is used to arrive
+ at the results of Example 9.15.
+
+ // 9.17
+
+ // Pole placement controller using internal model principle, as discussed in
+ Sec. 9.4.
+
+ // 9.8
+
+
+ // function [Rc,Sc,Tc,gamma,phit] = pp_im(B,A,k,phi,Delta)
+
+ // Calculates 2-DOF pole placement controller.
+
+
+ function [Rc,Sc,Tc,gamm] = pp_im(B,A,k,phi,Delta)
+
+
+ // Setting up and solving Aryabhatta identity
+
+ [Ag,Ab] = polsplit3(A); dAb = length(Ab) - 1;
+
+ [Bg,Bb] = polsplit3(B); dBb = length(Bb) - 1;
+
+
+ [zk,dzk] = zpowk(k);
+
+
+ [N,dN] = polmul(Bb,dBb,zk,dzk);
+
+ dDelta = length(Delta)-1;
+
+ [D,dD] = polmul(Ab,dAb,Delta,dDelta);
+
+ dphi = length(phi)-1;
+
+
+ [S1,dS1,R1,dR1] = xdync(N,dN,D,dD,phi,dphi);
+
+
+ // Determination of control law
+
+ Rc = convol(Bg,convol(R1,Delta)); Sc = convol(Ag,S1);
+
+ Tc = Ag; gamm = sum(phi)/sum(Bb);
+
+ endfunction;
+
+ // Solution to Aryabhatta''s identity arising in PID controller design, namely
+ Eq. 9.37 on page 363.
+
+ // 9.20
+
+
+ function [Rc,Sc] = pp_pid(B,A,k,phi,Delta)
+
+
+ // Setting up and solving Aryabhatta identity
+
+ dB = length(B) - 1; dA = length(A) - 1;
+
+ [zk,dzk] = zpowk(k);
+
+ [N,dN] = polmul(B,dB,zk,dzk);
+
+ dDelta = length(Delta)-1;
+
+ [D,dD] = polmul(A,dA,Delta,dDelta);
+
+ dphi = length(phi)-1;
+
+ [Sc,dSc,R,dR] = xdync(N,dN,D,dD,phi,dphi);
+
+ Rc = convol(R,Delta);
+
+ endfunction;
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1; end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // test problem to demonstrate benefits of 2_dof
+
+ // Ts = 1; B = [1 0.9]; A = conv([1 -1],[1 -0.8]); k = 1;
+
+ Ts = 1; k = 1;
+
+ B = convol([1 0.9],[1 -0.8]); A = convol([1 -1],[1 -0.5]);
+
+
+ // closed loop characteristic polynomial
+
+ phi = [1 -1 0.5];
+
+
+ Delta = 1; // Choice of internal model of step
+
+ control = 1;
+
+ if control == 1, // 1-DOF with no cancellation
+
+ [Rc,Sc] = pp_pid(B,A,k,phi,Delta);
+
+ Tc = Sc; gamm = 1;
+
+ else // 2-DOF
+
+ [Rc,Sc,Tc,gamm] = pp_im(B,A,k,phi,Delta);
+
+ end
+
+
+ // simulation parameters for stb_disc.mdl
+
+ [zk,dzk] = zpowk(k);
+
+ st = 1; // desired step change
+
+ t_init = 0; // simulation start time
+
+ t_final = 20; // simulation end time
+
+ xInitial = [0 0];
+
+ C = 0; D = 1; N_var = 0;
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Rcp1,Rcp2] = cosfil_ip(1,Rc); // 1/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Bp,Ap] = cosfil_ip(B,A); // B/A
+
+ [zkp1,zkp2] = cosfil_ip(zk,1); // zk/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D'
- model: saveAPI.gallery
- pk: 655
+ pk: 34
fields:
save_id: gallery33
name: Ex9_18
description: 'Digital Control (Author: K. M. Moudgalya), 9) Pole Placement Controllers,
9.18) Anti windup control of IBM Lotus Domino server'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="1000.0" title="stb_disc_sat"><!--Xcos - 1.0 - scilab-5.5.2
@@ -52361,14 +63252,1223 @@
as="geometry" height="20.0" width="60.0" x="670.0" y="160.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-98b0b2b:146d610f05a:-78c3" parent="-98b0b2b:146d610f05a:-78c2"/></XcosDiagram>
media: gallery33.png
+ script_dump: '// Anti windup control (AWC) of IBM Lotus Domino server, studied
+ in Example 9.16 on page 357. It can be used for the follwoing situations: with
+ and without saturation, and with and without AWC.
+
+ // 9.18
+
+ // Pole placement controller without intra sample oscillations, as discussed
+ in Sec. 9.5.
+
+ // 9.13
+
+
+ // function [Rc,Sc,Tc,gamma,phit] = pp_im2(B,A,k,phi,Delta,a)
+
+ // 2-DOF PP controller with internal model of Delta and without
+
+ // hidden oscillations
+
+
+ function [Rc,Sc,Tc,gamm,phit] = pp_im2(B,A,k,phi,Delta,a)
+
+
+ if argn(2) == 5, a = 1; end
+
+ dphi = length(phi)-1;
+
+
+ // Setting up and solving Aryabhatta identity
+
+ [Ag,Ab] = polsplit3(A,a); dAb = length(Ab) - 1;
+
+ [Bg,Bb] = polsplit3(B,a); dBb = length(Bb) - 1;
+
+
+ [zk,dzk] = zpowk(k);
+
+
+ [N,dN] = polmul(Bb,dBb,zk,dzk);
+
+ dDelta = length(Delta)-1;
+
+ [D,dD] = polmul(Ab,dAb,Delta,dDelta);
+
+
+ [S1,dS1,R1,dR1] = xdync(N,dN,D,dD,phi,dphi);
+
+
+ // Determination of control law
+
+ Rc = convol(Bg,convol(R1,Delta)); Sc = convol(Ag,S1);
+
+ Tc = Ag; gamm = sum(phi)/sum(Bb);
+
+
+ // Total characteristic polynomial
+
+ phit = convol(phi,convol(Ag,Bg));
+
+ endfunction;
+
+
+ // Calculation of desired closed loop characteristic polynomial, as discussed
+ in Sec. 7.7.
+
+ // 9.4
+
+
+ // function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ // Based on transient requirements,
+
+ // calculates closed loop characteristic polynomial
+
+
+ function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ Nr = rise/Ts; omega = %pi/2/Nr; rho = epsilon^(omega/%pi);
+
+ phi = [1 -2*rho*cos(omega) rho^2]; dphi = length(phi)-1;
+
+ endfunction;
+
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // Procedure to split a polynomial into good and bad factors, as discussed in
+ Sec. 9.5. The factors that have roots outside unit circle or with negative real
+ parts are defined as bad.
+
+ // 9.12
+
+
+ // function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ // Splits a scalar polynomial of z^{-1} into good and bad
+
+ // factors. Input is a polynomial in increasing degree of
+
+ // z^{-1}. Optional input is a, where a <= 1.
+
+ // Factors that have roots outside a circle of radius a or
+
+ // with negative roots will be called bad and the rest
+
+ // good. If a is not specified, it will be assumed as 1.
+
+
+ function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ if argn(2) == 1, a = 1; end
+
+ if a>1 error(''good polynomial also is unstable''); end
+
+ fac1 = poly(fac(length(fac):-1:1),''z'',''coeff'');
+
+ rts = roots(fac1);
+
+ rts = rts(length(rts):-1:1);
+
+
+ // extract good and bad roots
+
+ badindex = mtlb_find((abs(rts)>=a-1.0e-5)|(real(rts)<-0.05));
+
+ badpoly = coeff(poly(rts(badindex),''z''));
+
+ goodindex = mtlb_find((abs(rts)<a-1.0e-5)&(real(rts)>=-0.05));
+
+ goodpoly = coeff(poly(rts(goodindex),''z''));
+
+
+ // scale by equating the largest terms
+
+ [m,index] = max(abs(fac));
+
+ goodbad = convol(goodpoly,badpoly);
+
+ goodbad = goodbad(length(goodbad):-1:1);
+
+ factor1 = fac(index)/goodbad(index);
+
+ goodpoly = goodpoly * factor1;
+
+ goodpoly = goodpoly(length(goodpoly):-1:1);
+
+ badpoly = badpoly(length(badpoly):-1:1);
+
+ endfunction;
+
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1;
+
+ end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+ function [C,degC] = poladd(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= cB | rA ~= rB
+
+ error(''poladd: Inconsistent dimensions'');
+
+ end
+
+
+ degC = max(degA,degB);
+
+ if degC >= degA
+
+ A = [A zeros(rA,(degC-degA)*cA)];
+
+ end
+
+ if degC >= degB
+
+ B = [B zeros(rB,(degC-degB)*cB)];
+
+ end
+
+ C = A+B;
+
+ endfunction;
+
+
+ // Transfer function
+
+ B = 0.47; A = [1 -0.43]; k = 1;
+
+ [zk,dzk] = zpowk(k);
+
+
+ // Transient specifications
+
+ rise = 10; epsilon = 0.01; Ts = 1;
+
+ phi = desired(Ts,rise,epsilon);
+
+
+ // Controller design
+
+ delta = [1 -1]; // internal model of step used
+
+ [Rc,Sc,Tc,gamm,F] = pp_im2(B,A,k,phi,delta);
+
+
+ // Study of Antiwindup Controller
+
+
+ // Set key between 1 and 4
+
+ // key = 1: Simulate without any saturation limits
+
+ // key = 2: Simulate saturation, but do not use AWC
+
+ // key = 3: Simulate saturation with AWC in place
+
+ // key = 4: Simulate with AWC, without saturation limits
+
+ key=1
+
+
+ if key ==0
+
+ disp(''Invalid choice'');
+
+ return;
+
+ elseif key == 1
+
+ U = 2; L = -2; P = 1; F = Rc; E = 0; PSc = Sc; PTc = Tc;
+
+ elseif key == 2
+
+ U = 1; L = -1; P = 1; F = Rc; E = 0; PSc = Sc; PTc = Tc;
+
+ else
+
+ if key == 3 // Antiwindup controller and with saturation
+
+ U = 1; L = -1;
+
+ elseif key == 4 // Antiwindup controller, but no saturation
+
+ U = 2; L = -2;
+
+ else
+
+ disp(''Invalid choice'');
+
+ return;
+
+ end
+
+ P = A;
+
+ dF = length(F) - 1;
+
+ PRc = convol(P,Rc); dPRc = length(PRc) - 1;
+
+ [E,dE] = poladd(F,dF,-PRc,dPRc);
+
+ PSc = convol(P,Sc); PTc = convol(P,Tc);
+
+ end
+
+
+ // Setting up simulation parameters for stb_disc_sat
+
+ t_init = 0; // first step begins
+
+ st = 1; // height of first step
+
+ t_init2 = 500; // second step begins
+
+ st2 = -2; // height of second step
+
+ t_final = 1000; // simulation end time
+
+ st1 = 0; // no disturbance input
+
+ C = 0; D = 1; N_var = 0;
+
+
+ [PTcp1,PTcp2] = cosfil_ip(PTc,1); // PTc/1
+
+ [Fp1,Fp2] = cosfil_ip(1,F); // 1/F
+
+ [Ep,Fp] = cosfil_ip(E,F); // E/F
+
+ [PScp1,PScp2] = cosfil_ip(PSc,1); // PSc/1
+
+ [Bp,Ap] = cosfil_ip(B,A); // B/A
+
+ [zkp1,zkp2] = cosfil_ip(zk,1); // zk/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D'
- model: saveAPI.gallery
- pk: 656
+ pk: 35
fields:
save_id: gallery34
name: Ex9_19
description: 'Digital Control (Author: K. M. Moudgalya), 9) Pole Placement Controllers,
9.19) Demonstration of usefulness of negative PID parameters'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="20.0" title="g_s_cl"><!--Xcos - 1.0 - scilab-5.5.2 - 20150331
@@ -54844,14 +66944,1866 @@
as="geometry" height="40.0" width="100.0" x="450.0" y="420.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-7dc40e71:146d783a328:-7fa0" parent="-7dc40e71:146d783a328:-7f9f"/></XcosDiagram>
media: gallery34.png
+ script_dump: '// Demonstration of usefulness of negative PID parameters, discussed
+ in Example 9.17 on page 361.
+
+ // 9.19
+
+ funcprot(0)
+
+ function Hd=iodelay(H,d)
+
+ if or(size(H.num)<>size(d)) then error(''Dimension mismatch''),end
+
+ Hd=mlist([''rd'',''H'',''iodelay''],H,d)
+
+ endfunction
+
+
+ //element wise product overloading functions
+
+ function H=%rd_x_rd(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=mlist([''rd'',''H'',''iodelay''],H1.H.*H2.H,H1.iodelay+ H2.iodelay)
+
+ endfunction
+
+ function H=%rd_x_r(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=mlist([''rd'',''H'',''iodelay''],H1.H.*H2,H1.iodelay)
+
+ endfunction
+
+ function H=%r_x_rd(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=mlist([''rd'',''H'',''iodelay''],H1.*H2.H,H2.iodelay)
+
+ endfunction
+
+ function H=%rd_x_s(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=mlist([''rd'',''H'',''iodelay''],H1.H.*H2,H1.iodelay)
+
+ endfunction
+
+ function H=%s_x_rd(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=mlist([''rd'',''H'',''iodelay''],H1.*H2.H,H2.iodelay)
+
+ endfunction
+
+
+ //column concatenation overloading functions
+
+ function H=%rd_c_rd(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=mlist([''rd'',''H'',''iodelay''],[H1.H H2.H],[H1.iodelay,H2.iodelay])
+
+ endfunction
+
+ function H=%rd_c_r(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=mlist([''rd'',''H'',''iodelay''],[H1.H H2],[H1.iodelay,zeros(H2.num)])
+
+ endfunction
+
+ function H=%r_c_rd(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=mlist([''rd'',''H'',''iodelay''],[H1 H2.H],[zeros(H1.num),H2.iodelay])
+
+ endfunction
+
+ function H=%rd_c_s(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=mlist([''rd'',''H'',''iodelay''],[H1.H H2],[H1.iodelay,zeros(H2.num)])
+
+ endfunction
+
+ function H=%s_c_rd(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=mlist([''rd'',''H'',''iodelay''],[H1 H2.H],[zeros(H1.num),H2.iodelay])
+
+ endfunction
+
+
+ //row concatenation overloading functions
+
+ function H=%rd_f_rd(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=mlist([''rd'',''H'',''iodelay''],[H1.H;H2.H],[H1.iodelay;H2.iodelay])
+
+ endfunction
+
+ function H=%rd_f_r(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=mlist([''rd'',''H'',''iodelay''],[H1.H;H2],[H1.iodelay;zeros(H2.num)])
+
+ endfunction
+
+ function H=%r_f_rd(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=mlist([''rd'',''H'',''iodelay''],[H1;H2.H],[zeros(H1.num);H2.iodelay])
+
+ endfunction
+
+ function H=%rd_f_s(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=mlist([''rd'',''H'',''iodelay''],[H1.H;H2],[H1.iodelay;zeros(H2.num)])
+
+ endfunction
+
+ function H=%s_f_rd(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=mlist([''rd'',''H'',''iodelay''],[H1;H2.H],[zeros(H1.num);H2.iodelay])
+
+ endfunction
+
+
+ //matrix product overloading functions
+
+ function H=%rd_m_rd(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ D1=H1.iodelay
+
+ D2=H2.iodelay
+
+ D=D1*D2;
+
+ for k=1;size(D2,2)
+
+ for l=1:size(D1,1)
+
+ d=D1(l,:)+(D2(:,k)'')
+
+ if or(d(1)<>d) then error(''Delays mismatched''),end
+
+ D(l,k)=d
+
+ end
+
+ end
+
+ H=mlist([''rd'',''H'',''iodelay''],H1.H*H2.H,D)
+
+ endfunction
+
+ function H=%rd_m_r(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ D1=H1.iodelay
+
+ for l=1:size(D1,1)
+
+ if or(D1(l,1)<>D1(l,:)) then error(''Delays mismatched''),end
+
+ end
+
+ H=mlist([''rd'','''',''iodelay''],H1.H*H2,D1)
+
+ endfunction
+
+ function H=%rd_m_s(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ D1=H1.iodelay
+
+ for l=1:size(D1,1)
+
+ if or(D1(l,1)<>D1(l,:)) then error(''Delays mismatched''),end
+
+ end
+
+ H=mlist([''rd'',''H'',''iodelay''],H1.H*H2,D1)
+
+ endfunction
+
+ function H=%r_m_rd(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ D2=H2.iodelay
+
+ for l=1:size(D2,2)
+
+ if or(D2(1,l)<>D2(:,l)) then error(''Delays mismatched''),end
+
+ end
+
+ H=mlist([''rd'',''H'',''iodelay''],H1*H2.H,D2)
+
+ endfunction
+
+ function H=%s_m_rd(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ D2=H2.iodelay
+
+ for l=1:size(D2,2)
+
+ if or(D2(1,l)<>D2(:,l)) then error(''Delays mismatched''),end
+
+ end
+
+ H=mlist([''rd'',''H'',''iodelay''],H1*H2.H,D2)
+
+ endfunction
+
+
+ //Addition overloading functions
+
+ function H=%rd_a_rd(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ D1=H1.iodelay
+
+ D2=H2.iodelay
+
+ if or(D1<>D2) then error(''Delay mismatch''),end
+
+ H=mlist([''rd'',''H'',''iodelay''],H1.H+H2.H,D1)
+
+ endfunction
+
+ function H=%rd_a_r(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ D1=H1.iodelay
+
+ if or(D1<>0) then error(''Delay mismatch''),end
+
+ H=mlist([''rd'',''H'',''iodelay''],H1.H+H2,D1)
+
+ endfunction
+
+ function H=%rd_a_s(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ D1=H1.iodelay
+
+ if or(D1<>0) then error(''Delay mismatch''),end
+
+ H=mlist([''rd'',''H'',''iodelay''],H1.H+H2,D1)
+
+ endfunction
+
+ function H=%r_a_rd(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ D2=H2.iodelay
+
+ if or(D2<>0) then error(''Delay mismatch''),end
+
+ H=mlist([''rd'',''H'',''iodelay''],H1+H2.H,D2)
+
+ endfunction
+
+
+ //Substraction overloading functions
+
+ function H=%rd_a_rd(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ D1=H1.iodelay
+
+ D2=H2.iodelay
+
+ if or(D1<>D2) then error(''Delay mismatch''),end
+
+ H=mlist([''rd'',''H'',''iodelay''],H1.H-H2.H,D1)
+
+ endfunction
+
+ function H=%rd_a_r(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ D1=H1.iodelay
+
+ if or(D1<>0) then error(''Delay mismatch''),end
+
+ H=mlist([''rd'',''H'',''iodelay''],H1.H-H2,D1)
+
+ endfunction
+
+ function H=%rd_a_s(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ D1=H1.iodelay
+
+ if or(D1<>0) then error(''Delay mismatch''),end
+
+ H=mlist([''rd'',''H'',''iodelay''],H1.H-H2,D1)
+
+ endfunction
+
+ function H=%r_a_rd(H1,H2)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ D2=H2.iodelay
+
+ if or(D2<>0) then error(''Delay mismatch''),end
+
+ H=mlist([''rd'',''H'',''iodelay''],H1-H2.H,D2)
+
+ endfunction
+
+
+ //extraction overloading functions
+
+ function H=%rd_e(varargin)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=varargin($)
+
+ Hh= H.H;Hh.num=Hh.num(varargin(1:$-1));Hh.den=Hh.den(varargin(1:$-1));
+
+ H.H=Hh
+
+ H.iodelay=H.iodelay(varargin(1:$-1))
+
+ endfunction
+
+
+ //insertion overloading functions
+
+ function H=%rd_i_rd(varargin)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=varargin($)
+
+ Hfrom=varargin($-1)
+
+
+ Hh= H.H
+
+ Hh.num(varargin(1:$-2))=Hfrom.H.num
+
+ Hh.den(varargin(1:$-2))=Hfrom.H.den
+
+ H.H=Hh
+
+ H.iodelay(varargin(1:$-2))=Hfrom.iodelay
+
+ endfunction
+
+ function H=%r_i_rd(varargin)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=varargin($)
+
+ Hfrom=varargin($-1)
+
+
+ Hh= H.H
+
+ Hh.num(varargin(1:$-2))=Hfrom.num
+
+ Hh.den(varargin(1:$-2))=Hfrom.den
+
+ H.H=Hh
+
+ H.iodelay(varargin(1:$-2))=zeros(Hfrom.num)
+
+ endfunction
+
+ function H=%s_i_rd(varargin)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=varargin($)
+
+ Hfrom=varargin($-1)
+
+
+ Hh= H.H
+
+ Hh.num(varargin(1:$-2))=Hfrom
+
+ Hh.den(varargin(1:$-2))=ones(Hfrom)
+
+ H.H=Hh
+
+ H.iodelay(varargin(1:$-2))=zeros(Hfrom)
+
+ endfunction
+
+ function H=%rd_i_r(varargin)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ Hh=varargin($)
+
+ Hfrom=varargin($-1)
+
+ Hh.num(varargin(1:$-2))=Hfrom.H.num
+
+ Hh.den(varargin(1:$-2))=Hfrom.H.den
+
+ D=zeros(Hh.num)
+
+ D(varargin(1:$-2))=Hfrom.iodelay
+
+ H=mlist([''rd'',''H'',''iodelay''],Hh,D)
+
+ endfunction
+
+ function H=%rd_i_s(varargin)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ num=varargin($);den=ones(num)
+
+ Hfrom=varargin($-1)
+
+
+ num(varargin(1:$-2))=Hfrom.H.num
+
+ den(varargin(1:$-2))=Hfrom.H.den
+
+ D=zeros(num)
+
+ D(varargin(1:$-2))=Hfrom.iodelay
+
+ H=mlist([''rd'',''H'',''iodelay''],rlist(num,den,''c''),D)
+
+ endfunction
+
+
+ //transpostion overloading function
+
+ function H=%rd_t(H)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H.H=H.H''
+
+ H.iodelay=H.iodelay''
+
+ endfunction
+
+
+ //string overloading function
+
+ function txt=%rd_string(H)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ r=H.H
+
+ N=string(r.num)
+
+ D=string(r.den)
+
+ ln=max(matrix(length(N),2,-1),''r'')
+
+ ld=max(matrix(length(D),2,-1),''r'')
+
+ l=max(ln,ld)
+
+ [m,n]=size(r.num);
+
+ S=emptystr(m,n)
+
+
+ kz=find(H.iodelay==0);//zero delay entries
+
+ w=''exp(''+string(-H.iodelay)+''*s)*'';w(kz)='''';
+
+
+ for i=1:m*n
+
+ s=2*i-1:2*i
+
+ pw=part('' '',1:length(w(i)))
+
+ N(s)=pw+part('' '',1:(l(i)-ln(i))/2)+N(s)
+
+ D(s)=pw+part('' '',1:(l(i)-ld(i))/2)+D(s)
+
+ S(i) =w(i)+part(''-'',ones(1,l(i)))
+
+ end
+
+ txt=emptystr(5*m,n);
+
+ txt(1:5:$,:)=N(1:2:$,:)
+
+ txt(2:5:$,:)=N(2:2:$,:)
+
+ txt(3:5:$,:)=S(1:$,:)
+
+ txt(4:5:$,:)=D(1:2:$,:)
+
+ txt(5:5:$,:)=D(2:2:$,:)
+
+ endfunction
+
+
+
+ //Display overloading function
+
+ function %rd_p(H)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ //used to display rational fraction with complex coefficients
+
+ //The real case is hard coded
+
+ // Copyright INRIA
+
+ T=string(H)
+
+ l=max(length(T),''r'')
+
+ Te=emptystr(size(T,1),1)
+
+ for k=1:size(T,2)
+
+ Te=Te+part(T(:,k),1:l(k)+1)+'' ''
+
+ end
+
+ mprintf("%s\n",Te)
+
+ endfunction
+
+
+
+ //frequency response computation overloading
+
+ function [frq,repf,splitf]=repfreq(varargin)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=varargin(1)
+
+ autolib.repfreq
+
+ if typeof(H)==''rd'' then
+
+ D=H.iodelay
+
+ varargin(1)=H.H
+
+ [frq,repf,splitf]=repfreq(varargin(:))
+
+
+ w=-2*%i*%pi*frq;
+
+ for k=1:size(D,''*'')
+
+ repf(k,:)=repf(k,:).*exp(D(k)*w)
+
+ end
+
+ else
+
+ [frq,repf,splitf]=repfreq(varargin(:))
+
+ end
+
+ endfunction
+
+
+ //bode plot computation overloading
+
+ function bode(varargin)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=varargin(1)
+
+ xdesslib.bode
+
+ if typeof(H)==''rd'' then
+
+ if type(varargin($))==10 then //a comment
+
+ cm=varargin($);varagin($)=null()
+
+ else
+
+ cm=''''
+
+ end
+
+ D=H.iodelay
+
+ varargin(1)=H.H
+
+ [frq,repf,splitf]=repfreq(varargin(1:$))
+
+ w=-2*%i*%pi*frq;
+
+ for k=1:size(D,''*'')
+
+ repf(k,:)=repf(k,:).*exp(D(k)*w)
+
+ end
+
+ bode(frq,repf)
+
+ else
+
+ bode(varargin(:))
+
+ end
+
+ endfunction
+
+
+ //nyquist plot computation overloading
+
+ function nyquist(varargin)
+
+ // Author: Serge Steer, Copyright INRIA
+
+ H=varargin(1)
+
+ xdesslib.nyquist
+
+ if typeof(H)==''rd'' then
+
+ if type(varargin($))==10 then //a comment
+
+ cm=varargin($);varagin($)=null()
+
+ else
+
+ cm=''''
+
+ end
+
+ D=H.iodelay
+
+ varargin(1)=H.H
+
+ [frq,repf,splitf]=repfreq(varargin(1:$))
+
+ w=-2*%i*%pi*frq;
+
+ for k=1:size(D,''*'')
+
+ repf(k,:)=repf(k,:).*exp(D(k)*w)
+
+ end
+
+ nyquist(frq,repf)
+
+ else
+
+ nyquist(varargin(:))
+
+ end
+
+ endfunction
+
+
+ // Discretizing a tf with delay
+
+ // Exact solution
+
+ // Applicable for a 1st order system
+
+
+ // Ref.: pg.287,Digital Control,Prof.Kannan Moudgalya
+
+
+ // D: Delay
+
+ // TF: e^(-Ds) OR e^(-Ds)
+
+ // ------------ ------------ (gen.)
+
+ // tau*s + 1 tau*s + a
+
+
+ //D = kTs + D'' (gen.)
+
+ // G: TF with delay component
+
+ // G1: TF with zero delay
+
+ // Required because G cannot be directly used in Scilab
+
+ // Coefficients are returned for ascending powers of z^-1
+
+
+ function [B,A,k1] = delc2d(G,G1,Ts)
+
+ D = G.iodelay;
+
+ d = coeff(G1(''den''));
+
+ if d(1) == 1
+
+ tau = d(2);
+
+ mu = 1;
+
+ else
+
+ tau = d(2)/d(1);
+
+ mu = 1/d(1);
+
+ end;
+
+
+ k = floor(D/Ts);
+
+ Dpri = D - k*Ts;
+
+ Dis = ((%z*(1 - (exp(-(Ts - Dpri)/tau)) ) )+ (exp(-(Ts - Dpri)/tau) - exp(-Ts/tau)
+ ))/ ((%z^(k+1))*(%z - exp(-Ts/tau)))
+
+ Dis1 = Dis*mu;
+
+ disp(''Warning: Exact discretization of first order system only'');
+
+ k1 = degree(Dis1(''den'')) - degree(Dis1(''num''));
+
+ B = coeff(Dis1(''num''));
+
+ A = coeff(Dis1(''den''));
+
+ B = flip(B);
+
+ A = flip(A);
+
+ endfunction;
+
+
+
+
+
+
+
+
+
+
+ // Calculation of desired closed loop characteristic polynomial, as discussed
+ in Sec. 7.7.
+
+ // 9.4
+
+
+ // function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ // Based on transient requirements,
+
+ // calculates closed loop characteristic polynomial
+
+
+ function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ Nr = rise/Ts; omega = %pi/2/Nr; rho = epsilon^(omega/%pi);
+
+ phi = [1 -2*rho*cos(omega) rho^2]; dphi = length(phi)-1;
+
+ endfunction;
+
+ // Solution to Aryabhatta''s identity arising in PID controller design, namely
+ Eq. 9.37 on page 363.
+
+ // 9.20
+
+
+ function [Rc,Sc] = pp_pid(B,A,k,phi,Delta)
+
+
+ // Setting up and solving Aryabhatta identity
+
+ dB = length(B) - 1; dA = length(A) - 1;
+
+ [zk,dzk] = zpowk(k);
+
+ [N,dN] = polmul(B,dB,zk,dzk);
+
+ dDelta = length(Delta)-1;
+
+ [D,dD] = polmul(A,dA,Delta,dDelta);
+
+ dphi = length(phi)-1;
+
+ [Sc,dSc,R,dR] = xdync(N,dN,D,dD,phi,dphi);
+
+ Rc = convol(R,Delta);
+
+ endfunction;
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ //User defined function
+
+ //Forms a transfer function
+
+ //Scilab: Co efficients are given in increasing power of variable
+
+ //Matlab: Co efficients are given in decreasing power of variable
+
+ //Hence co efficients are flipped here
+
+
+ //Input arguments: (1) Numerator co efficients(decreasing order)
+
+ //(2) Denominator co efficients
+
+ //(3) Variable to specify domain
+
+
+ // Updated (30-11-06)
+
+ // System is continuous => a is not passed
+
+ // System is discrete => a = -1
+
+ // System is discretized (sampled system) => a = Ts
+
+ // Uses syslin
+
+
+ function trfu = tf(num,den,a)
+
+ if argn(2) == 2
+
+ d = ''c'';
+
+ elseif a == -1
+
+ d = ''d'';
+
+ else
+
+ d = a
+
+ end;
+
+ num = clean(num);
+
+ den = clean(den);
+
+ num1 = poly(num(length(num):-1:1),''x'',''coeff'');
+
+ den1 = poly(den(length(den):-1:1),''x'',''coeff'');
+
+ trfu = syslin(d,num1,den1);
+
+ endfunction;
+
+
+
+
+ // 10.5
+
+ function b = flip(a)
+
+ b = a(length(a):-1:1);
+
+ endfunction;
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1; end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+
+ // Discretize the continuous plant
+
+ num = 1; den = [2 1]; tau = 0.5;
+
+ G1 = tf(num,den);
+
+ G = iodelay(G1,tau);
+
+ Ts = 0.5;
+
+ [B,A,k] = delc2d(G,G1,Ts);
+
+
+ // Specify transient requirements
+
+ epsilon = 0.05; rise = 5;
+
+ phi = desired(Ts,rise,epsilon);
+
+
+ // Design the controller
+
+ Delta = [1 -1];
+
+ [Rc,Sc] = pp_pid(B,A,k,phi,Delta);
+
+
+ // parameters for simulation using g_s_cl
+
+ Tc = Sc; gamm = 1; N = 1;
+
+ C = 0; D = 1; N_var = 0;
+
+ st = 1; t_init = 0; t_final = 20;
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Np,Rcp] = cosfil_ip(N,Rc); // N/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D
+
+ Num = numer(G1);
+
+ Den = denom(G1);'
- model: saveAPI.gallery
- pk: 657
+ pk: 36
fields:
save_id: gallery35
name: Ex9_1_1
description: 'Digital Control (Author: K. M. Moudgalya), 9) Pole Placement Controllers,
9.1) Pole placement controller for magnetically suspended ball problem'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.5" title="basic"><!--Xcos - 1.0 - scilab-5.5.2 - 20150331
@@ -57029,14 +70981,1171 @@
as="geometry" height="40.0" width="50.0" x="530.0" y="290.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-64ce6d85:145ef6f2b4f:-7f9f" parent="-64ce6d85:145ef6f2b4f:-7f9e"/></XcosDiagram>
media: gallery35.png
+ script_dump: '// Pole placement controller for magnetically suspended ball problem,
+ discussed in Example 9.3 on page 331.
+
+ // 9.1
+
+ // Discretization of continuous transfer function. The result is numerator and
+ denominator in powers of z^{-1} and the delay term k.
+
+ // 9.2
+
+ // function [B,A,k] = myc2d(G,Ts)
+
+ // Produces numerator and denominator of discrete transfer
+
+ // function in powers of z^{-1}
+
+ // G is continuous transfer function; time delays are not allowed
+
+ // Ts is the sampling time, all in consistent time units
+
+
+ function [B,A,k] = myc2d(G,Ts)
+
+ H = ss2tf(dscr(G,Ts));
+
+ num1 = coeff(H(''num''));
+
+ den1 = coeff(H(''den''));//-------------
+
+ A = den1(length(den1):-1:1);
+
+ num2 = num1(length(num1):-1:1); //flip
+
+ nonzero = find(num1);
+
+ first_nz = nonzero(1);
+
+ B = num2(first_nz:length(num2)); //-------------
+
+ k = length(den1) - length(num1);
+
+ endfunction
+
+
+ // Calculation of desired closed loop characteristic polynomial, as discussed
+ in Sec. 7.7.
+
+ // 9.4
+
+
+ // function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ // Based on transient requirements,
+
+ // calculates closed loop characteristic polynomial
+
+
+ function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ Nr = rise/Ts; omega = %pi/2/Nr; rho = epsilon^(omega/%pi);
+
+ phi = [1 -2*rho*cos(omega) rho^2]; dphi = length(phi)-1;
+
+ endfunction;
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+ // Procedure to split a polynomial into good and bad factors, as discussed in
+ Sec. 9.2.
+
+ // 9.3
+
+ // function [goodpoly,badpoly] = polsplit2(fac,a)
+
+ // Splits a scalar polynomial of z^{-1} into good and bad
+
+ // factors.
+
+ // Input is a polynomial in increasing degree of z^{-1}
+
+ // Optional input is a, where a <= 1.
+
+ // Factor that has roots of z^{-1} outside a is called
+
+ // good and the rest bad.
+
+ // If a is not specified, it will be assumed as 1-1.0e-5
+
+
+ function [goodpoly,badpoly] = polsplit2(fac,a)
+
+ if argn(2) == 1, a = 1-1.0e-5; end
+
+ if a>1 error(''good polynomial is unstable''); end
+
+ fac1 = poly(fac(length(fac):-1:1),''z'',''coeff'');
+
+ rts1 = roots(fac1);
+
+ rts = rts1(length(rts1):-1:1);
+
+
+ // extract good and bad roots
+
+ badindex = find(abs(rts)>=a); // mtlb_find has been replaced by find
+
+ badpoly = coeff(poly((rts(badindex)),"z","roots"));
+
+ goodindex = find(abs(rts)<a); // mtlb_find has been replaced by find
+
+ goodpoly = coeff(poly(rts(goodindex),"z","roots"));
+
+
+ // scale by equating the largest terms
+
+ [m,index] = max(abs(fac));
+
+ goodbad = convol(goodpoly,badpoly);
+
+ goodbad1 = goodbad(length(goodbad):-1:1);//--
+
+ factor1 = fac(index)/goodbad1(index);//--
+
+ goodpoly = goodpoly * factor1;
+
+ goodpoly = goodpoly(length(goodpoly):-1:1);
+
+ badpoly = badpoly(length(badpoly):-1:1);
+
+ endfunction;
+
+
+
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1; end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+ // Design of 2-DOF pole placement controller, as discussed in Sec. 9.2.
+
+ // 9.5
+
+
+ // function [Rc,Sc,Tc,gamma] = pp_basic(B,A,k,phi)
+
+ // calculates pole placement controller
+
+
+
+ function [Rc,Sc,Tc,gamm] = pp_basic(B,A,k,phi)
+
+
+ // Setting up and solving Aryabhatta identity
+
+ [Ag,Ab] = polsplit2(A); dAb = length(Ab) - 1;
+
+ [Bg,Bb] = polsplit2(B); dBb = length(Bb) - 1;
+
+
+ [zk,dzk] = zpowk(k);
+
+
+ [N,dN] = polmul(Bb,dBb,zk,dzk);
+
+ dphi = length(phi) - 1;
+
+
+ [S1,dS1,R1,dR1] = xdync(N,dN,Ab,dAb,phi,dphi);
+
+
+ // Determination of control law
+
+ Rc = convol(Bg,R1); Sc = convol(Ag,S1);
+
+ Tc = Ag; gamm = sum(phi)/sum(Bb);
+
+
+ endfunction;
+
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // Magnetically suspended ball problem
+
+ // Operating conditions
+
+ M = 0.05; L = 0.01; R = 1; K = 0.0001; g = 9.81;
+
+
+ //Equilibrium conditions
+
+ hs = 0.01; is = sqrt(M*g*hs/K);
+
+
+ // State space matrices
+
+ a21 = K*is^2/M/hs^2; a23 = - 2*K*is/M/hs; a33 = - R/L;
+
+ b3 = 1/L;
+
+ a1 = [0 1 0; a21 0 a23; 0 0 a33];
+
+ b1 = [0; 0; b3]; c1 = [1 0 0]; d1 = 0;
+
+
+ // Transfer functions
+
+ G = syslin(''c'',a1,b1,c1,d1); Ts = 0.01;
+
+ [B,A,k] = myc2d(G,Ts);
+
+
+ //polynomials are returned
+
+ [Ds,num,den] = ss2tf(G);
+
+ num = clean(num); den = clean(den);
+
+
+ // Transient specifications
+
+ rise = 0.15; epsilon = 0.05;
+
+ phi = desired(Ts,rise,epsilon);
+
+
+ // Controller design
+
+ [Rc,Sc,Tc,gamm] = pp_basic(B,A,k,phi);
+
+
+ // Setting up simulation parameters for basic.xcos
+
+ st = 0.0001; // desired change in h, in m.
+
+ t_init = 0; // simulation start time
+
+ t_final = 0.5; // simulation end time
+
+
+ // Setting up simulation parameters for c_ss_cl.xcos
+
+ N_var = 0; xInitial = [0 0 0]; N = 1; C = 0; D = 1;
+
+
+ [Tc1,Rc1] = cosfil_ip(Tc,Rc); // Tc/Rc
+
+ [Sc2,Rc2] = cosfil_ip(Sc,Rc); // Sc/Rc
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Np,Rcp] = cosfil_ip(N,Rc); // 1/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D'
- model: saveAPI.gallery
- pk: 658
+ pk: 37
fields:
save_id: gallery36
name: Ex9_1_2
description: 'Digital Control (Author: K. M. Moudgalya), 9) Pole Placement Controllers,
9.1) Pole placement controller for magnetically suspended ball problem'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.5" title="Ex9_1_2"><!--Xcos - 1.0 - scilab-5.5.2 - 20150331
@@ -59365,14 +74474,1171 @@
as="geometry" height="40.0" width="60.0" x="560.0" y="230.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="3844e477:143914d2fde:-7fa0" parent="3844e477:143914d2fde:-7f9f"/></XcosDiagram>
media: gallery36.png
+ script_dump: '// Pole placement controller for magnetically suspended ball problem,
+ discussed in Example 9.3 on page 331.
+
+ // 9.1
+
+ // Discretization of continuous transfer function. The result is numerator and
+ denominator in powers of z^{-1} and the delay term k.
+
+ // 9.2
+
+ // function [B,A,k] = myc2d(G,Ts)
+
+ // Produces numerator and denominator of discrete transfer
+
+ // function in powers of z^{-1}
+
+ // G is continuous transfer function; time delays are not allowed
+
+ // Ts is the sampling time, all in consistent time units
+
+
+ function [B,A,k] = myc2d(G,Ts)
+
+ H = ss2tf(dscr(G,Ts));
+
+ num1 = coeff(H(''num''));
+
+ den1 = coeff(H(''den''));//-------------
+
+ A = den1(length(den1):-1:1);
+
+ num2 = num1(length(num1):-1:1); //flip
+
+ nonzero = find(num1);
+
+ first_nz = nonzero(1);
+
+ B = num2(first_nz:length(num2)); //-------------
+
+ k = length(den1) - length(num1);
+
+ endfunction
+
+
+ // Calculation of desired closed loop characteristic polynomial, as discussed
+ in Sec. 7.7.
+
+ // 9.4
+
+
+ // function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ // Based on transient requirements,
+
+ // calculates closed loop characteristic polynomial
+
+
+ function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ Nr = rise/Ts; omega = %pi/2/Nr; rho = epsilon^(omega/%pi);
+
+ phi = [1 -2*rho*cos(omega) rho^2]; dphi = length(phi)-1;
+
+ endfunction;
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+ // Procedure to split a polynomial into good and bad factors, as discussed in
+ Sec. 9.2.
+
+ // 9.3
+
+ // function [goodpoly,badpoly] = polsplit2(fac,a)
+
+ // Splits a scalar polynomial of z^{-1} into good and bad
+
+ // factors.
+
+ // Input is a polynomial in increasing degree of z^{-1}
+
+ // Optional input is a, where a <= 1.
+
+ // Factor that has roots of z^{-1} outside a is called
+
+ // good and the rest bad.
+
+ // If a is not specified, it will be assumed as 1-1.0e-5
+
+
+ function [goodpoly,badpoly] = polsplit2(fac,a)
+
+ if argn(2) == 1, a = 1-1.0e-5; end
+
+ if a>1 error(''good polynomial is unstable''); end
+
+ fac1 = poly(fac(length(fac):-1:1),''z'',''coeff'');
+
+ rts1 = roots(fac1);
+
+ rts = rts1(length(rts1):-1:1);
+
+
+ // extract good and bad roots
+
+ badindex = find(abs(rts)>=a); // mtlb_find has been replaced by find
+
+ badpoly = coeff(poly((rts(badindex)),"z","roots"));
+
+ goodindex = find(abs(rts)<a); // mtlb_find has been replaced by find
+
+ goodpoly = coeff(poly(rts(goodindex),"z","roots"));
+
+
+ // scale by equating the largest terms
+
+ [m,index] = max(abs(fac));
+
+ goodbad = convol(goodpoly,badpoly);
+
+ goodbad1 = goodbad(length(goodbad):-1:1);//--
+
+ factor1 = fac(index)/goodbad1(index);//--
+
+ goodpoly = goodpoly * factor1;
+
+ goodpoly = goodpoly(length(goodpoly):-1:1);
+
+ badpoly = badpoly(length(badpoly):-1:1);
+
+ endfunction;
+
+
+
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1; end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+ // Design of 2-DOF pole placement controller, as discussed in Sec. 9.2.
+
+ // 9.5
+
+
+ // function [Rc,Sc,Tc,gamma] = pp_basic(B,A,k,phi)
+
+ // calculates pole placement controller
+
+
+
+ function [Rc,Sc,Tc,gamm] = pp_basic(B,A,k,phi)
+
+
+ // Setting up and solving Aryabhatta identity
+
+ [Ag,Ab] = polsplit2(A); dAb = length(Ab) - 1;
+
+ [Bg,Bb] = polsplit2(B); dBb = length(Bb) - 1;
+
+
+ [zk,dzk] = zpowk(k);
+
+
+ [N,dN] = polmul(Bb,dBb,zk,dzk);
+
+ dphi = length(phi) - 1;
+
+
+ [S1,dS1,R1,dR1] = xdync(N,dN,Ab,dAb,phi,dphi);
+
+
+ // Determination of control law
+
+ Rc = convol(Bg,R1); Sc = convol(Ag,S1);
+
+ Tc = Ag; gamm = sum(phi)/sum(Bb);
+
+
+ endfunction;
+
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // Magnetically suspended ball problem
+
+ // Operating conditions
+
+ M = 0.05; L = 0.01; R = 1; K = 0.0001; g = 9.81;
+
+
+ //Equilibrium conditions
+
+ hs = 0.01; is = sqrt(M*g*hs/K);
+
+
+ // State space matrices
+
+ a21 = K*is^2/M/hs^2; a23 = - 2*K*is/M/hs; a33 = - R/L;
+
+ b3 = 1/L;
+
+ a1 = [0 1 0; a21 0 a23; 0 0 a33];
+
+ b1 = [0; 0; b3]; c1 = [1 0 0]; d1 = 0;
+
+
+ // Transfer functions
+
+ G = syslin(''c'',a1,b1,c1,d1); Ts = 0.01;
+
+ [B,A,k] = myc2d(G,Ts);
+
+
+ //polynomials are returned
+
+ [Ds,num,den] = ss2tf(G);
+
+ num = clean(num); den = clean(den);
+
+
+ // Transient specifications
+
+ rise = 0.15; epsilon = 0.05;
+
+ phi = desired(Ts,rise,epsilon);
+
+
+ // Controller design
+
+ [Rc,Sc,Tc,gamm] = pp_basic(B,A,k,phi);
+
+
+ // Setting up simulation parameters for basic.xcos
+
+ st = 0.0001; // desired change in h, in m.
+
+ t_init = 0; // simulation start time
+
+ t_final = 0.5; // simulation end time
+
+
+ // Setting up simulation parameters for c_ss_cl.xcos
+
+ N_var = 0; xInitial = [0 0 0]; N = 1; C = 0; D = 1;
+
+
+ [Tc1,Rc1] = cosfil_ip(Tc,Rc); // Tc/Rc
+
+ [Sc2,Rc2] = cosfil_ip(Sc,Rc); // Sc/Rc
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Np,Rcp] = cosfil_ip(N,Rc); // 1/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D'
- model: saveAPI.gallery
- pk: 659
+ pk: 38
fields:
save_id: gallery37
name: Ex9_21_1
description: 'Digital Control (Author: K. M. Moudgalya), 9) Pole Placement Controllers,
9.21) DC motor with PID control tuned through pole placement technique'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="20.0" title="Ex9_21_1"><!--Xcos - 1.0 - scilab-5.5.2 -
@@ -61920,14 +78186,1121 @@
as="geometry" height="40.0" width="40.0" x="460.0" y="360.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-75a601dc:14604d880d0:-7ffd" parent="-75a601dc:14604d880d0:-7ffc"/></XcosDiagram>
media: gallery37.png
+ script_dump: '// DC motor with PID control, tuned through pole placement technique,
+ as in Example 9.18.
+
+ // 9.21
+
+ // Calculation of desired closed loop characteristic polynomial, as discussed
+ in Sec. 7.7.
+
+ // 9.4
+
+
+ // function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ // Based on transient requirements,
+
+ // calculates closed loop characteristic polynomial
+
+
+ function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ Nr = rise/Ts; omega = %pi/2/Nr; rho = epsilon^(omega/%pi);
+
+ phi = [1 -2*rho*cos(omega) rho^2]; dphi = length(phi)-1;
+
+ endfunction;
+
+ // Solution to Aryabhatta''s identity arising in PID controller design, namely
+ Eq. 9.37 on page 363.
+
+ // 9.20
+
+
+ function [Rc,Sc] = pp_pid(B,A,k,phi,Delta)
+
+
+ // Setting up and solving Aryabhatta identity
+
+ dB = length(B) - 1; dA = length(A) - 1;
+
+ [zk,dzk] = zpowk(k);
+
+ [N,dN] = polmul(B,dB,zk,dzk);
+
+ dDelta = length(Delta)-1;
+
+ [D,dD] = polmul(A,dA,Delta,dDelta);
+
+ dphi = length(phi)-1;
+
+ [Sc,dSc,R,dR] = xdync(N,dN,D,dD,phi,dphi);
+
+ Rc = convol(R,Delta);
+
+ endfunction;
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // PD control law from polynomial coefficients, as explained in Sec. 9.8.
+
+ // 9.22
+
+
+ function [K,taud,N] = pd(Rc,Sc,Ts)
+
+
+ // Both Rc and Sc have to be degree one polynomials
+
+
+ s0 = Sc(1); s1 = Sc(2);
+
+ r1 = Rc(2);
+
+ K = (s0+s1)/(1+r1);
+
+ N = (s1-s0*r1)/r1/(s0+s1);
+
+ taudbyN = -Ts*r1/(1+r1);
+
+ taud = taudbyN * N;
+
+ endfunction;
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+ // Discretization of continuous transfer function. The result is numerator and
+ denominator in powers of z^{-1} and the delay term k.
+
+ // 9.2
+
+ // function [B,A,k] = myc2d(G,Ts)
+
+ // Produces numerator and denominator of discrete transfer
+
+ // function in powers of z^{-1}
+
+ // G is continuous transfer function; time delays are not allowed
+
+ // Ts is the sampling time, all in consistent time units
+
+
+ function [B,A,k] = myc2d(G,Ts)
+
+ H = ss2tf(dscr(G,Ts));
+
+ num1 = coeff(H(''num''));
+
+ den1 = coeff(H(''den''));//-------------
+
+ A = den1(length(den1):-1:1);
+
+ num2 = num1(length(num1):-1:1); //flip
+
+ nonzero = find(num1);
+
+ first_nz = nonzero(1);
+
+ B = num2(first_nz:length(num2)); //-------------
+
+ k = length(den1) - length(num1);
+
+ endfunction
+
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1; end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+
+ // Motor control problem
+
+ // Transfer function
+
+
+ a = [-1 0; 1 0]; b = [1; 0]; c = [0 1]; d = 0;
+
+ G = syslin(''c'',a,b,c,d); Ts = 0.25;
+
+ [B,A,k] = myc2d(G,Ts);
+
+ [Ds,num,den] = ss2tf(G);
+
+
+ // Transient specifications
+
+ rise = 3; epsilon = 0.05;
+
+ phi = desired(Ts,rise,epsilon);
+
+
+ // Controller design
+
+ Delta = 1; //No internal model of step used
+
+ [Rc,Sc] = pp_pid(B,A,k,phi,Delta);
+
+
+ // continuous time controller
+
+ [K,taud,N] = pd(Rc,Sc,Ts);
+
+ numb = K*[1 taud*(1+1/N)]; denb = [1 taud/N];
+
+ numf = 1; denf = 1;
+
+
+ // simulation parameters
+
+ st = 1; // desired change in position
+
+ t_init = 0; // simulation start time
+
+ t_final = 20; // simulation end time
+
+ st1 = 0;
+
+
+ // continuous controller simulation: g_s_cl3.xcos
+
+ num1 = 0; den1 = 1;
+
+
+ // discrete controller simulation: g_s_cl2.xcos
+
+ // u1: -0.1 to 0.8
+
+ // y1: 0 to 1.4
+
+ C = 0; D = 1; N = 1; gamm = 1; Tc = Sc;
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Np,Rcp] = cosfil_ip(N,Rc); // N/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D
+
+ Numb = polyno(numb,''s'');
+
+ Denb = polyno(denb,''s'');
+
+ Numf = polyno(numf,''s'');
+
+ Denf = polyno(denf,''s'');
+
+ Num1 = polyno(num1,''s'');
+
+ Den1 = polyno(den1,''s'');'
- model: saveAPI.gallery
- pk: 660
+ pk: 39
fields:
save_id: gallery38
name: Ex9_21_2
description: 'Digital Control (Author: K. M. Moudgalya), 9) Pole Placement Controllers,
9.21) DC motor with PID control tuned through pole placement technique'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="20.0" title="Ex9_21_2"><!--Xcos - 1.0 - scilab-5.5.2 -
@@ -64457,14 +81830,1121 @@
x="540.0" y="210.0"/><mxPoint as="targetPoint" x="570.0" y="210.0"/></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="7b254bcc:14613988545:-7cfe" parent="7b254bcc:14613988545:-7cfd"/></XcosDiagram>
media: gallery38.png
+ script_dump: '// DC motor with PID control, tuned through pole placement technique,
+ as in Example 9.18.
+
+ // 9.21
+
+ // Calculation of desired closed loop characteristic polynomial, as discussed
+ in Sec. 7.7.
+
+ // 9.4
+
+
+ // function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ // Based on transient requirements,
+
+ // calculates closed loop characteristic polynomial
+
+
+ function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ Nr = rise/Ts; omega = %pi/2/Nr; rho = epsilon^(omega/%pi);
+
+ phi = [1 -2*rho*cos(omega) rho^2]; dphi = length(phi)-1;
+
+ endfunction;
+
+ // Solution to Aryabhatta''s identity arising in PID controller design, namely
+ Eq. 9.37 on page 363.
+
+ // 9.20
+
+
+ function [Rc,Sc] = pp_pid(B,A,k,phi,Delta)
+
+
+ // Setting up and solving Aryabhatta identity
+
+ dB = length(B) - 1; dA = length(A) - 1;
+
+ [zk,dzk] = zpowk(k);
+
+ [N,dN] = polmul(B,dB,zk,dzk);
+
+ dDelta = length(Delta)-1;
+
+ [D,dD] = polmul(A,dA,Delta,dDelta);
+
+ dphi = length(phi)-1;
+
+ [Sc,dSc,R,dR] = xdync(N,dN,D,dD,phi,dphi);
+
+ Rc = convol(R,Delta);
+
+ endfunction;
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // PD control law from polynomial coefficients, as explained in Sec. 9.8.
+
+ // 9.22
+
+
+ function [K,taud,N] = pd(Rc,Sc,Ts)
+
+
+ // Both Rc and Sc have to be degree one polynomials
+
+
+ s0 = Sc(1); s1 = Sc(2);
+
+ r1 = Rc(2);
+
+ K = (s0+s1)/(1+r1);
+
+ N = (s1-s0*r1)/r1/(s0+s1);
+
+ taudbyN = -Ts*r1/(1+r1);
+
+ taud = taudbyN * N;
+
+ endfunction;
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+ // Discretization of continuous transfer function. The result is numerator and
+ denominator in powers of z^{-1} and the delay term k.
+
+ // 9.2
+
+ // function [B,A,k] = myc2d(G,Ts)
+
+ // Produces numerator and denominator of discrete transfer
+
+ // function in powers of z^{-1}
+
+ // G is continuous transfer function; time delays are not allowed
+
+ // Ts is the sampling time, all in consistent time units
+
+
+ function [B,A,k] = myc2d(G,Ts)
+
+ H = ss2tf(dscr(G,Ts));
+
+ num1 = coeff(H(''num''));
+
+ den1 = coeff(H(''den''));//-------------
+
+ A = den1(length(den1):-1:1);
+
+ num2 = num1(length(num1):-1:1); //flip
+
+ nonzero = find(num1);
+
+ first_nz = nonzero(1);
+
+ B = num2(first_nz:length(num2)); //-------------
+
+ k = length(den1) - length(num1);
+
+ endfunction
+
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1; end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+
+ // Motor control problem
+
+ // Transfer function
+
+
+ a = [-1 0; 1 0]; b = [1; 0]; c = [0 1]; d = 0;
+
+ G = syslin(''c'',a,b,c,d); Ts = 0.25;
+
+ [B,A,k] = myc2d(G,Ts);
+
+ [Ds,num,den] = ss2tf(G);
+
+
+ // Transient specifications
+
+ rise = 3; epsilon = 0.05;
+
+ phi = desired(Ts,rise,epsilon);
+
+
+ // Controller design
+
+ Delta = 1; //No internal model of step used
+
+ [Rc,Sc] = pp_pid(B,A,k,phi,Delta);
+
+
+ // continuous time controller
+
+ [K,taud,N] = pd(Rc,Sc,Ts);
+
+ numb = K*[1 taud*(1+1/N)]; denb = [1 taud/N];
+
+ numf = 1; denf = 1;
+
+
+ // simulation parameters
+
+ st = 1; // desired change in position
+
+ t_init = 0; // simulation start time
+
+ t_final = 20; // simulation end time
+
+ st1 = 0;
+
+
+ // continuous controller simulation: g_s_cl3.xcos
+
+ num1 = 0; den1 = 1;
+
+
+ // discrete controller simulation: g_s_cl2.xcos
+
+ // u1: -0.1 to 0.8
+
+ // y1: 0 to 1.4
+
+ C = 0; D = 1; N = 1; gamm = 1; Tc = Sc;
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Np,Rcp] = cosfil_ip(N,Rc); // N/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D
+
+ Numb = polyno(numb,''s'');
+
+ Denb = polyno(denb,''s'');
+
+ Numf = polyno(numf,''s'');
+
+ Denf = polyno(denf,''s'');
+
+ Num1 = polyno(num1,''s'');
+
+ Den1 = polyno(den1,''s'');'
- model: saveAPI.gallery
- pk: 661
+ pk: 40
fields:
save_id: gallery39
name: basic_disc
description: 'Digital Control (Author: K. M. Moudgalya), 9) Pole Placement Controllers,
9.7) Simulation of closed loop system with an unstable controller'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="1000.0" title="basic_disc"><!--Xcos - 1.0 - scilab-5.5.2
@@ -66643,14 +85123,1179 @@
scilabClass="ScilabList"><mxPoint x="750.0" y="290.0"/></Array></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-7476484f:145f8cd2a3c:-7f9e" parent="-7476484f:145f8cd2a3c:-7f9d"/></XcosDiagram>
media: gallery39.png
+ script_dump: '// Simulation of closed loop system with an unstable controller,
+ as discussed in Example 9.5 on page 335.
+
+ // 9.7
+
+
+ // function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ // Based on transient requirements,
+
+ // calculates closed loop characteristic polynomial
+
+
+ function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ Nr = rise/Ts; omega = %pi/2/Nr; rho = epsilon^(omega/%pi);
+
+ phi = [1 -2*rho*cos(omega) rho^2]; dphi = length(phi)-1;
+
+ endfunction;
+
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+
+ // Procedure to split a polynomial into good and bad factors, as discussed in
+ Sec. 9.2.
+
+ // 9.3
+
+ // function [goodpoly,badpoly] = polsplit2(fac,a)
+
+ // Splits a scalar polynomial of z^{-1} into good and bad
+
+ // factors.
+
+ // Input is a polynomial in increasing degree of z^{-1}
+
+ // Optional input is a, where a <= 1.
+
+ // Factor that has roots of z^{-1} outside a is called
+
+ // good and the rest bad.
+
+ // If a is not specified, it will be assumed as 1-1.0e-5
+
+
+ function [goodpoly,badpoly] = polsplit2(fac,a)
+
+ if argn(2) == 1, a = 1-1.0e-5; end
+
+ if a>1 error(''good polynomial is unstable''); end
+
+ fac1 = poly(fac(length(fac):-1:1),''z'',''coeff'');
+
+ rts1 = roots(fac1);
+
+ rts = rts1(length(rts1):-1:1);
+
+
+ // extract good and bad roots
+
+ badindex = find(abs(rts)>=a); // mtlb_find has been replaced by find
+
+ badpoly = coeff(poly((rts(badindex)),"z","roots"));
+
+ goodindex = find(abs(rts)<a); // mtlb_find has been replaced by find
+
+ goodpoly = coeff(poly(rts(goodindex),"z","roots"));
+
+
+ // scale by equating the largest terms
+
+ [m,index] = max(abs(fac));
+
+ goodbad = convol(goodpoly,badpoly);
+
+ goodbad1 = goodbad(length(goodbad):-1:1);//--
+
+ factor1 = fac(index)/goodbad1(index);//--
+
+ goodpoly = goodpoly * factor1;
+
+ goodpoly = goodpoly(length(goodpoly):-1:1);
+
+ badpoly = badpoly(length(badpoly):-1:1);
+
+ endfunction;
+
+
+ // Procedure to split a polynomial into good and bad factors, as discussed in
+ Sec. 9.5. The factors that have roots outside unit circle or with negative real
+ parts are defined as bad.
+
+ // 9.12
+
+
+ // function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ // Splits a scalar polynomial of z^{-1} into good and bad
+
+ // factors. Input is a polynomial in increasing degree of
+
+ // z^{-1}. Optional input is a, where a <= 1.
+
+ // Factors that have roots outside a circle of radius a or
+
+ // with negative roots will be called bad and the rest
+
+ // good. If a is not specified, it will be assumed as 1.
+
+
+ function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ if argn(2) == 1, a = 1; end
+
+ if a>1 error(''good polynomial also is unstable''); end
+
+ fac1 = poly(fac(length(fac):-1:1),''z'',''coeff'');
+
+ rts = roots(fac1);
+
+ rts = rts(length(rts):-1:1);
+
+
+ // extract good and bad roots
+
+ badindex = mtlb_find((abs(rts)>=a-1.0e-5)|(real(rts)<-0.05));
+
+ badpoly = coeff(poly(rts(badindex),''z''));
+
+ goodindex = mtlb_find((abs(rts)<a-1.0e-5)&(real(rts)>=-0.05));
+
+ goodpoly = coeff(poly(rts(goodindex),''z''));
+
+
+ // scale by equating the largest terms
+
+ [m,index] = max(abs(fac));
+
+ goodbad = convol(goodpoly,badpoly);
+
+ goodbad = goodbad(length(goodbad):-1:1);
+
+ factor1 = fac(index)/goodbad(index);
+
+ goodpoly = goodpoly * factor1;
+
+ goodpoly = goodpoly(length(goodpoly):-1:1);
+
+ badpoly = badpoly(length(badpoly):-1:1);
+
+ endfunction;
+
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1; end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // Design of 2-DOF pole placement controller, as discussed in Sec. 9.2.
+
+ // 9.5
+
+
+ // function [Rc,Sc,Tc,gamma] = pp_basic(B,A,k,phi)
+
+ // calculates pole placement controller
+
+
+
+ function [Rc,Sc,Tc,gamm] = pp_basic(B,A,k,phi)
+
+
+ // Setting up and solving Aryabhatta identity
+
+ [Ag,Ab] = polsplit2(A); dAb = length(Ab) - 1;
+
+ [Bg,Bb] = polsplit2(B); dBb = length(Bb) - 1;
+
+
+ [zk,dzk] = zpowk(k);
+
+
+ [N,dN] = polmul(Bb,dBb,zk,dzk);
+
+ dphi = length(phi) - 1;
+
+
+ [S1,dS1,R1,dR1] = xdync(N,dN,Ab,dAb,phi,dphi);
+
+
+ // Determination of control law
+
+ Rc = convol(Bg,R1); Sc = convol(Ag,S1);
+
+ Tc = Ag; gamm = sum(phi)/sum(Bb);
+
+
+ endfunction;
+
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+
+ Ts = 1; B = [1 -3]; A = [1 2 -8]; k = 1;
+
+ // Since k=1, tf is of the form z^-1
+
+ [zk,dzk] = zpowk(k); // int1 = 0;//---- int1
+
+
+ // Transient specifications
+
+ rise = 10; epsilon = 0.1;
+
+ phi = desired(Ts,rise,epsilon);
+
+
+ // Controller design
+
+ [Rc,Sc,Tc,gamm] = pp_basic(B,A,k,phi);
+
+
+ // simulation parameters for basic_disc.xcos
+
+ //While simulating for t_final = 100, set the limit of Y axis of each scope
+
+ //u1: -0.2 to 3
+
+ //y1: -0.1 to 1.2
+
+ st = 1.0; // Desired change in setpoint
+
+ t_init = 0; // Simulation start time
+
+ t_final = 1000; // Simulation end time
+
+
+ // Simulation parameters for stb_disc.xcos
+
+ N_var = 0; C = 0; D = 1; N = 1;
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Rcp1,Rcp2] = cosfil_ip(1,Rc); // 1/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Bp,Ap] = cosfil_ip(B,A); // B/A
+
+ [zkp1,zkp2] = cosfil_ip(zk,1); // zk/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D
+
+
+ [Tcp,Rcp] = cosfil_ip(Tc,Rc); // Tc/Rc
+
+ [Scp_b,Rcp_b] = cosfil_ip(Sc,Rc); // Sc/Rc'
- model: saveAPI.gallery
- pk: 662
+ pk: 41
fields:
save_id: gallery40
name: stb_disc
description: 'Digital Control (Author: K. M. Moudgalya), 9) Pole Placement Controllers,
9.7) Simulation of closed loop system with an unstable controller'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.5" title="stb_disc"><!--Xcos - 1.0 - scilab-5.5.2 -
@@ -68994,15 +88639,1180 @@
x="370.0" y="140.0"/></Array></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-7476484f:145f8cd2a3c:-7be9" parent="-7476484f:145f8cd2a3c:-7be8"/></XcosDiagram>
media: gallery40.png
+ script_dump: '// Simulation of closed loop system with an unstable controller,
+ as discussed in Example 9.5 on page 335.
+
+ // 9.7
+
+
+ // function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ // Based on transient requirements,
+
+ // calculates closed loop characteristic polynomial
+
+
+ function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ Nr = rise/Ts; omega = %pi/2/Nr; rho = epsilon^(omega/%pi);
+
+ phi = [1 -2*rho*cos(omega) rho^2]; dphi = length(phi)-1;
+
+ endfunction;
+
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+
+ // Procedure to split a polynomial into good and bad factors, as discussed in
+ Sec. 9.2.
+
+ // 9.3
+
+ // function [goodpoly,badpoly] = polsplit2(fac,a)
+
+ // Splits a scalar polynomial of z^{-1} into good and bad
+
+ // factors.
+
+ // Input is a polynomial in increasing degree of z^{-1}
+
+ // Optional input is a, where a <= 1.
+
+ // Factor that has roots of z^{-1} outside a is called
+
+ // good and the rest bad.
+
+ // If a is not specified, it will be assumed as 1-1.0e-5
+
+
+ function [goodpoly,badpoly] = polsplit2(fac,a)
+
+ if argn(2) == 1, a = 1-1.0e-5; end
+
+ if a>1 error(''good polynomial is unstable''); end
+
+ fac1 = poly(fac(length(fac):-1:1),''z'',''coeff'');
+
+ rts1 = roots(fac1);
+
+ rts = rts1(length(rts1):-1:1);
+
+
+ // extract good and bad roots
+
+ badindex = find(abs(rts)>=a); // mtlb_find has been replaced by find
+
+ badpoly = coeff(poly((rts(badindex)),"z","roots"));
+
+ goodindex = find(abs(rts)<a); // mtlb_find has been replaced by find
+
+ goodpoly = coeff(poly(rts(goodindex),"z","roots"));
+
+
+ // scale by equating the largest terms
+
+ [m,index] = max(abs(fac));
+
+ goodbad = convol(goodpoly,badpoly);
+
+ goodbad1 = goodbad(length(goodbad):-1:1);//--
+
+ factor1 = fac(index)/goodbad1(index);//--
+
+ goodpoly = goodpoly * factor1;
+
+ goodpoly = goodpoly(length(goodpoly):-1:1);
+
+ badpoly = badpoly(length(badpoly):-1:1);
+
+ endfunction;
+
+
+ // Procedure to split a polynomial into good and bad factors, as discussed in
+ Sec. 9.5. The factors that have roots outside unit circle or with negative real
+ parts are defined as bad.
+
+ // 9.12
+
+
+ // function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ // Splits a scalar polynomial of z^{-1} into good and bad
+
+ // factors. Input is a polynomial in increasing degree of
+
+ // z^{-1}. Optional input is a, where a <= 1.
+
+ // Factors that have roots outside a circle of radius a or
+
+ // with negative roots will be called bad and the rest
+
+ // good. If a is not specified, it will be assumed as 1.
+
+
+ function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ if argn(2) == 1, a = 1; end
+
+ if a>1 error(''good polynomial also is unstable''); end
+
+ fac1 = poly(fac(length(fac):-1:1),''z'',''coeff'');
+
+ rts = roots(fac1);
+
+ rts = rts(length(rts):-1:1);
+
+
+ // extract good and bad roots
+
+ badindex = mtlb_find((abs(rts)>=a-1.0e-5)|(real(rts)<-0.05));
+
+ badpoly = coeff(poly(rts(badindex),''z''));
+
+ goodindex = mtlb_find((abs(rts)<a-1.0e-5)&(real(rts)>=-0.05));
+
+ goodpoly = coeff(poly(rts(goodindex),''z''));
+
+
+ // scale by equating the largest terms
+
+ [m,index] = max(abs(fac));
+
+ goodbad = convol(goodpoly,badpoly);
+
+ goodbad = goodbad(length(goodbad):-1:1);
+
+ factor1 = fac(index)/goodbad(index);
+
+ goodpoly = goodpoly * factor1;
+
+ goodpoly = goodpoly(length(goodpoly):-1:1);
+
+ badpoly = badpoly(length(badpoly):-1:1);
+
+ endfunction;
+
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1; end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // Design of 2-DOF pole placement controller, as discussed in Sec. 9.2.
+
+ // 9.5
+
+
+ // function [Rc,Sc,Tc,gamma] = pp_basic(B,A,k,phi)
+
+ // calculates pole placement controller
+
+
+
+ function [Rc,Sc,Tc,gamm] = pp_basic(B,A,k,phi)
+
+
+ // Setting up and solving Aryabhatta identity
+
+ [Ag,Ab] = polsplit2(A); dAb = length(Ab) - 1;
+
+ [Bg,Bb] = polsplit2(B); dBb = length(Bb) - 1;
+
+
+ [zk,dzk] = zpowk(k);
+
+
+ [N,dN] = polmul(Bb,dBb,zk,dzk);
+
+ dphi = length(phi) - 1;
+
+
+ [S1,dS1,R1,dR1] = xdync(N,dN,Ab,dAb,phi,dphi);
+
+
+ // Determination of control law
+
+ Rc = convol(Bg,R1); Sc = convol(Ag,S1);
+
+ Tc = Ag; gamm = sum(phi)/sum(Bb);
+
+
+ endfunction;
+
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+
+ Ts = 1; B = [1 -3]; A = [1 2 -8]; k = 1;
+
+ // Since k=1, tf is of the form z^-1
+
+ [zk,dzk] = zpowk(k); // int1 = 0;//---- int1
+
+
+ // Transient specifications
+
+ rise = 10; epsilon = 0.1;
+
+ phi = desired(Ts,rise,epsilon);
+
+
+ // Controller design
+
+ [Rc,Sc,Tc,gamm] = pp_basic(B,A,k,phi);
+
+
+ // simulation parameters for basic_disc.xcos
+
+ //While simulating for t_final = 100, set the limit of Y axis of each scope
+
+ //u1: -0.2 to 3
+
+ //y1: -0.1 to 1.2
+
+ st = 1.0; // Desired change in setpoint
+
+ t_init = 0; // Simulation start time
+
+ t_final = 1000; // Simulation end time
+
+
+ // Simulation parameters for stb_disc.xcos
+
+ N_var = 0; C = 0; D = 1; N = 1;
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Rcp1,Rcp2] = cosfil_ip(1,Rc); // 1/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Bp,Ap] = cosfil_ip(B,A); // B/A
+
+ [zkp1,zkp2] = cosfil_ip(zk,1); // zk/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D
+
+
+ [Tcp,Rcp] = cosfil_ip(Tc,Rc); // Tc/Rc
+
+ [Scp_b,Rcp_b] = cosfil_ip(Sc,Rc); // Sc/Rc'
- model: saveAPI.gallery
- pk: 663
+ pk: 42
fields:
save_id: gallery41
name: Ex9_9
description: 'Digital Control (Author: K. M. Moudgalya), 9) Pole Placement Controllers,
9.9) Pole placement controller with internal model of a step for the magnetically
suspended ball problem'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2048
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.5" title="Ex9_9"><!--Xcos - 1.0 - scilab-5.5.2 - 20150331
@@ -71289,15 +92099,1157 @@
x="510.0" y="340.0"/><Array as="points" scilabClass=""><mxPoint x="510.0" y="440.0"/></Array></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="3af18dde:16fc1cf9366:-7cf3" parent="3af18dde:16fc1cf9366:-7cf2"/></XcosDiagram>
media: gallery41.png
+ script_dump: '// Pole placement controller, with internal model of a step, for
+ the magnetically suspended ball problem, as discussed in Example 9.8 on page
+ 339.
+
+ // 9.9
+
+ // Calculation of desired closed loop characteristic polynomial, as discussed
+ in Sec. 7.7.
+
+ // 9.4
+
+
+ // function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ // Based on transient requirements,
+
+ // calculates closed loop characteristic polynomial
+
+
+ function [phi,dphi] = desired(Ts,rise,epsilon)
+
+ Nr = rise/Ts; omega = %pi/2/Nr; rho = epsilon^(omega/%pi);
+
+ phi = [1 -2*rho*cos(omega) rho^2]; dphi = length(phi)-1;
+
+ endfunction;
+
+ // Pole placement controller using internal model principle, as discussed in
+ Sec. 9.4.
+
+ // 9.8
+
+
+ // function [Rc,Sc,Tc,gamma,phit] = pp_im(B,A,k,phi,Delta)
+
+ // Calculates 2-DOF pole placement controller.
+
+
+ function [Rc,Sc,Tc,gamm] = pp_im(B,A,k,phi,Delta)
+
+
+ // Setting up and solving Aryabhatta identity
+
+ [Ag,Ab] = polsplit3(A); dAb = length(Ab) - 1;
+
+ [Bg,Bb] = polsplit3(B); dBb = length(Bb) - 1;
+
+
+ [zk,dzk] = zpowk(k);
+
+
+ [N,dN] = polmul(Bb,dBb,zk,dzk);
+
+ dDelta = length(Delta)-1;
+
+ [D,dD] = polmul(Ab,dAb,Delta,dDelta);
+
+ dphi = length(phi)-1;
+
+
+ [S1,dS1,R1,dR1] = xdync(N,dN,D,dD,phi,dphi);
+
+
+ // Determination of control law
+
+ Rc = convol(Bg,convol(R1,Delta)); Sc = convol(Ag,S1);
+
+ Tc = Ag; gamm = sum(phi)/sum(Bb);
+
+ endfunction;
+
+ // Discretization of continuous transfer function. The result is numerator and
+ denominator in powers of z^{-1} and the delay term k.
+
+ // 9.2
+
+ // function [B,A,k] = myc2d(G,Ts)
+
+ // Produces numerator and denominator of discrete transfer
+
+ // function in powers of z^{-1}
+
+ // G is continuous transfer function; time delays are not allowed
+
+ // Ts is the sampling time, all in consistent time units
+
+
+ function [B,A,k] = myc2d(G,Ts)
+
+ H = ss2tf(dscr(G,Ts));
+
+ num1 = coeff(H(''num''));
+
+ den1 = coeff(H(''den''));//-------------
+
+ A = den1(length(den1):-1:1);
+
+ num2 = num1(length(num1):-1:1); //flip
+
+ nonzero = find(num1);
+
+ first_nz = nonzero(1);
+
+ B = num2(first_nz:length(num2)); //-------------
+
+ k = length(den1) - length(num1);
+
+ endfunction
+
+
+ // Procedure to split a polynomial into good and bad factors, as discussed in
+ Sec. 9.5. The factors that have roots outside unit circle or with negative real
+ parts are defined as bad.
+
+ // 9.12
+
+
+ // function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ // Splits a scalar polynomial of z^{-1} into good and bad
+
+ // factors. Input is a polynomial in increasing degree of
+
+ // z^{-1}. Optional input is a, where a <= 1.
+
+ // Factors that have roots outside a circle of radius a or
+
+ // with negative roots will be called bad and the rest
+
+ // good. If a is not specified, it will be assumed as 1.
+
+
+ function [goodpoly,badpoly] = polsplit3(fac,a)
+
+ if argn(2) == 1, a = 1; end
+
+ if a>1 error(''good polynomial also is unstable''); end
+
+ fac1 = poly(fac(length(fac):-1:1),''z'',''coeff'');
+
+ rts = roots(fac1);
+
+ rts = rts(length(rts):-1:1);
+
+
+ // extract good and bad roots
+
+ badindex = mtlb_find((abs(rts)>=a-1.0e-5)|(real(rts)<-0.05));
+
+ badpoly = coeff(poly(rts(badindex),''z''));
+
+ goodindex = mtlb_find((abs(rts)<a-1.0e-5)&(real(rts)>=-0.05));
+
+ goodpoly = coeff(poly(rts(goodindex),''z''));
+
+
+ // scale by equating the largest terms
+
+ [m,index] = max(abs(fac));
+
+ goodbad = convol(goodpoly,badpoly);
+
+ goodbad = goodbad(length(goodbad):-1:1);
+
+ factor1 = fac(index)/goodbad(index);
+
+ goodpoly = goodpoly * factor1;
+
+ goodpoly = goodpoly(length(goodpoly):-1:1);
+
+ badpoly = badpoly(length(badpoly):-1:1);
+
+ endfunction;
+
+ // Evaluates z^-k.
+
+ // 9.6
+
+
+ function [zk,dzk] = zpowk(k)
+
+ zk = zeros(1,k+1); zk(1,k+1) = 1;
+
+ dzk = k;
+
+ endfunction
+
+ // function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+ // MATLAB FUNCTION rowjoin TO SUPERPOSE TWO POLYNOMIAL
+
+ // MATRICES
+
+
+ // H. Kwakernaak, July, 1990
+
+
+ function [P,degP] = rowjoin(P1,degP1,P2,degP2)
+
+
+ [rP1,cP1] = polsize(P1,degP1);
+
+ [rP2,cP2] = polsize(P2,degP2);
+
+ if cP1 ~= cP2
+
+ error(''rowjoin: Inconsistent numbers of columns'');
+
+ end
+
+
+ rP = rP1+rP2; cP = cP1;
+
+ if degP1 >= degP2
+
+ degP = degP1;
+
+ else
+
+ degP = degP2;
+
+ end
+
+
+ if isempty(P1)
+
+ P = P2;
+
+ elseif isempty(P2)
+
+ P = P1;
+
+ else
+
+ P = zeros(rP,(degP+1)*cP);
+
+ P(1:rP1,1:(degP1+1)*cP1) = P1;
+
+ P(rP1+1:rP,1:(degP2+1)*cP2) = P2;
+
+ end
+
+ endfunction
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = ...
+
+ // left_prm(N,degN,D,degD,job,gap)
+
+ //
+
+ // does three different things according to integers that ''job'' takes
+
+ // job = 1.
+
+ // this is the default. It is always done for all jobs.
+
+ // -1 -1 -1
+
+ // Given ND , returns coprime B and A where ND = A B
+
+ // It is enough if one sends the first four input arguments
+
+ // If gap is required to be sent, then one can send either 1 or a null
+
+ // entry for job
+
+ // job = 2.
+
+ // first solve for job = 1 and then solve XA + YB = I
+
+ // job = 3.
+
+ // used in solving XD + YN = C
+
+ // after finding coprime factorization, data are returned
+
+ //
+
+ // convention: the variable with prefix deg stand for degrees
+
+ // of the corresponding polynomial matrices
+
+ //
+
+ // input:
+
+ // N: right fraction numerator polynomial matrix
+
+ // D: right fraction denominator polynomial matrix
+
+ // N and D are not neccessarily coprime
+
+ // gap: variable used to zero entries; default value is 1.0e+8
+
+ //
+
+ // output
+
+ // b and A are left coprime num. and den. polynomial matrices
+
+ // X and Y are solutions to Aryabhatta identity, only for job = 2
+
+
+ function [B,degB,A,degA,Y,degY,X,degX] = left_prm(N,degN,D,degD,job,gap)
+
+ if argn(2) == 4 | argn(2) == 5
+
+ gap = 1.0e8 ;
+
+ end
+
+ // pause
+
+ if argn(2) == 4,
+
+ job = 1; end
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+ [Frows,Fbcols] = polsize(F,degF); // Fbcols = block columns
+
+ Fcols = Fbcols * (degF+1) ; // actual columns of F
+
+ T1 = [];pr =[];degT1 = 0; T1rows = 0;shft = 0;
+
+ S=F; sel = ones(Frows,1); T1bcols =1;
+
+ abar = (Fbcols + 1):Frows; // a_super_bar of B-C.Chang
+
+ while isempty(T1) | T1rows < Frows - Fbcols
+
+ Srows = Frows*T1bcols; // max actual columns of result
+
+ [T1,T1rows,sel,pr] = ...
+
+ t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap);
+
+ [T1rows,T1cols] = size(T1);
+
+ if T1rows < Frows - Fbcols
+
+ T1 = [T1 zeros(T1rows,Frows)];
+
+ T1bcols = T1bcols + 1; // max. block columns of result
+
+ degT1 = degT1 + 1; // degree of result
+
+ shft = shft +Fbcols;
+
+ S = seshft(S,F,shft);
+
+ sel = [sel;sel(Srows-Frows+1:Srows)];
+
+ rowvec = (T1bcols-1)*Frows+(Fbcols+1):T1bcols * Frows;
+
+ abar = [abar rowvec]; // A_super_bar of B-C.chang
+
+ end
+
+ end
+
+
+ [B,degB,A,degA] = colsplit(T1,degT1,Fbcols,Frows-Fbcols);
+
+ [B,degB] = clcoef(B,degB);
+
+ B = -B;
+
+ [A,degA] = clcoef(A,degA);
+
+ // pause
+
+ if job == 2
+
+ S = S(mtlb_logical(sel),:); // columns
+
+ [redSrows,Scols] = size(S);
+
+ C = [eye(Fbcols,Fbcols) zeros(Fbcols,Scols-Fbcols)]; // append with zeros
+
+ T2 = C/S;
+
+ T2 = makezero(T2,gap);
+
+ T2 = move_sci(T2,find(sel),Srows);
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows - Fbcols);
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ elseif job == 3
+
+ Y = S;
+
+ degY = sel;
+
+ X = degT1;
+
+ degX = Fbcols;
+
+ else
+
+ if job ~= 1
+
+ error(''Message from left_prm:no legal job number specified'')
+
+ end
+
+ end
+
+ endfunction
+
+
+
+
+ // function [T1,T1rows,sel,pr] = ...
+
+ // t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ // calculates the coefficient matrix T1
+
+ // redundant row information is kept in sel: redundant rows are marked
+
+ // with zeros. The undeleted rows are marked with ones.
+
+
+ function [T1,T1rows,sel,pr] = t1calc(S,Srows,T1,T1rows,sel,pr,Frows,Fbcols,abar,gap)
+
+ b = 1; // vector of primary red.rows
+
+
+ while (T1rows < Frows - Fbcols) & or(sel==1) & ~isempty(b)
+
+ S = clean(S);
+
+ b = indep(S(mtlb_logical(sel),:),gap); // send selected rows of S
+
+ if ~isempty(b)
+
+ b = clean(b);
+
+ b = move_sci(b,find(sel),Srows);
+
+ j = length(b);
+
+ while ~(b(j) & or(abar==j)) // pick largest nonzero entry
+
+ j = j-1; // of coeff. belonging to abar
+
+ if ~j
+
+ fprintf(''\nMessage from t1calc, called from left_prm\n\n'')
+
+ error(''Denominator is noninvertible'')
+
+ end
+
+ end
+
+ if ~or(j<pr & pmodulo(pr,Frows) == pmodulo(j,Frows)) // pr(2),pr(1)
+
+ T1 = [T1; b]; // condition is not violated
+
+ T1rows = T1rows +1; // accept this vector
+
+ end // else don''t accept
+
+ pr = [pr; j]; // update prime red row info
+
+ while j <= Srows
+
+ sel(j) = 0;
+
+ j = j + Frows;
+
+ end
+
+ end
+
+ end
+
+ endfunction
+
+ // function b = indep(S,gap)
+
+ // determines the first row that is dependent on the previous rows of S.
+
+ // The coefficients of dependence is returned in b
+
+ function b = indep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ [rows,cols] = size(S);
+
+ ind = 1;
+
+ i = 2;
+
+ eps = 2.2204e-016;
+
+ while ind & i <= rows
+
+ sigma = svd(S(1:i,:));
+
+ len = length(sigma);
+
+ if(sigma(len)/sigma(1) < (eps*max(i,cols)))
+
+ ind =0;
+
+ else
+
+ shsig = [sigma(2:len);sigma(len)];
+
+ if or( (sigma ./shsig) > gap)
+
+ ind = 0;
+
+ else
+
+ ind = 1;
+
+ i = i+1;
+
+ end
+
+ end
+
+
+ end
+
+ if ind
+
+ b =[];
+
+
+ else
+
+ c = S(i,:)/S(1:i-1,:);
+
+ c = makezero(c,gap);
+
+ b = [-c 1];
+
+ end
+
+ endfunction
+
+
+ // function b = cindep( S,gap)
+
+ // Used in XD + YN = C. All rows except the last of are assumed to
+
+ // be independent. The aim is to check if the last row is dependent on the
+
+ // rest and if so how. The coefficients of dependence are sent in b.
+
+ function b = cindep( S,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ eps = 2.2204e-016;
+
+ [rows,cols] = size(S);
+
+ if rows > cols
+
+ ind = 0;
+
+ else
+
+ sigma = svd(S);
+
+ len = length(sigma);
+
+ if (sigma(len)/sigma(1) <= (eps*max(i,cols)))
+
+ ind = 0; //not independent
+
+ else
+
+ if or(sigma(1:len-1) ./sigma(2:len)>=gap)
+
+ ind = 0; // not dependent
+
+ else
+
+ ind = 1; //independent
+
+ end
+
+ end
+
+ end
+
+ if ind
+
+ b = [];
+
+ else
+
+ b = S(rows,:)/S(1:rows-1,:);
+
+ b = makezero(b,gap);
+
+ end
+
+ endfunction
+
+
+
+ // function C = seshft(A,B,N)
+
+ //given A and B matrices, returns C = [<-A-> 0
+
+ // 0 <-B->] with B shifted east by N cols
+
+
+ function C = seshft(A,B,N)
+
+ [Arows,Acols] = size(A);
+
+ [Brows,Bcols] = size(B);
+
+ if N >= 0
+
+ B = [zeros(Brows,N) B];
+
+ Bcols = Bcols + N;
+
+ elseif N < 0
+
+ A = [zeros(Arows,abs(N)) A];
+
+ Acols = Acols +abs(N);
+
+ end
+
+ if Acols < Bcols
+
+ A = [A zeros(Arows,Bcols-Acols)];
+
+ elseif Acols > Bcols
+
+ B = [B zeros(Brows,Acols-Bcols)];
+
+ end
+
+ C = [A
+
+ B];
+
+ endfunction
+
+ // function B = makezero(B,gap)
+
+ // where B is a vector and gap acts as a tolerance
+
+
+ function B = makezero(B,gap)
+
+
+ if argn(2) == 1
+
+ gap = 1.0e8;
+
+ end
+
+ temp = B(find(B)); // non zero entries of B
+
+ temp = -gsort(-abs(temp),''g'',''d''); // absolute values sorted in descending
+ order
+
+ len = length(temp);
+
+ ratio = temp(1:len-1) ./temp(2:len); // each ratio >1
+
+ min_ind = min(find(ratio>gap));
+
+ if ~isempty(min_ind)
+
+ our_eps = temp(min_ind+1);
+
+ zeroind = find(abs(B)<=our_eps);
+
+ B(zeroind) = zeros(1,length(zeroind));
+
+ end
+
+ endfunction
+
+ // function result = move_sci(b,nonred,max_sci)
+
+ // Moves matrix b to matrix result with the information on where to move,
+
+ // decided by the indices of nonred.
+
+ // The matrix result will have as many rows as b has and max number of columns.
+
+ // b is augumented with zeros to have nonred number of columns;
+
+ // The columns of b put into those of result as decided by nonred.
+
+
+ function result = move_sci(b,nonred,max_sci)
+
+ [brows,bcols] = size(b);
+
+ b = [b zeros(brows,length(nonred)-bcols)];
+
+ result = zeros(brows,max_sci);
+
+ result(:,nonred'') = b;
+
+ endfunction
+
+ // colsplit
+
+ // The command
+
+ // [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+ // produces two polynomial matrix P1 and P2. P1 consists of the first
+
+ // p1 columns of P and P2 consists of the remaining p2 columns of P.
+
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [P1,degP1,P2,degP2] = colsplit(P,degP,p1,p2)
+
+
+ if isempty(P)
+
+ P1 = []; P2 = [];
+
+ degP1 = 0; degP2 = 0;
+
+ return;
+
+ end
+
+
+ [rP,cP] = polsize(P,degP);
+
+ if p1 < 0 | p1 > cP | p2 < 0 | p2 > cP | p1+p2 ~= cP
+
+ error(''colsplit: Inconsistent numbers of columns'');
+
+ end
+
+ rP1 = rP; rP2 = rP; cP1 = p1; cP2 = p2;
+
+ degP1= degP; degP2 = degP;
+
+
+ if p1 == 0
+
+ P1 == []; P2 = P;
+
+ elseif p2 == 0
+
+ P1 = P; P2 = [];
+
+ else
+
+ P1 = zeros(rP1,(degP1+1)*cP1); P2 = zeros(rP2,(degP2+1)*cP2);
+
+ for i = 1:degP+1
+
+ P1(:,(i-1)*cP1+1:i*cP1) = P(:,(i-1)*cP+1:(i-1)*cP+cP1);
+
+ P2(:,(i-1)*cP2+1:i*cP2) = P(:,(i-1)*cP+cP1+1:i*cP);
+
+ end
+
+ end
+
+ endfunction;
+
+ // H. Kwakernaak, July, 1990
+
+ // Modified by Kannan Moudgalya in Nov. 1992
+
+
+ function [P,degP] = clcoef(Q,degQ)
+
+
+ [rQ,cQ] = polsize(Q,degQ);
+
+
+ if and(and(Q==0))
+
+ P = zeros(rQ,cQ);
+
+ degP = 0;
+
+ else
+
+ P = Q; degP = degQ; rP = rQ; cP = cQ;
+
+ j = degP+1;
+
+ while j >= 0
+
+ X = P(:,(j-1)*cP+1:j*cP)
+
+ if max(sum(abs(X''))) < (1e-8)*max(sum(abs(P)))
+
+ P = P(:,1:(j-1)*cP);
+
+ degP = degP-1;
+
+ else
+
+ j = 0;
+
+ end
+
+ j = j-1;
+
+ end
+
+ end
+
+ endfunction
+
+ // polmul
+
+ // The command
+
+ // [C,degA] = polmul(A,degA,B,degB)
+
+ // produces the polynomial matrix C that equals the product A*B of the
+
+ // polynomial matrices A and B.
+
+ //
+
+ // H. Kwakernaak, July, 1990
+
+
+
+ function [C,degC] = polmul(A,degA,B,degB)
+
+ [rA,cA] = polsize(A,degA);
+
+ [rB,cB] = polsize(B,degB);
+
+ if cA ~= rB
+
+ error(''polmul: Inconsistent dimensions of input matrices'');
+
+ end
+
+
+ degC = degA+degB;
+
+ C = [];
+
+ for k = 0:degA+degB
+
+ mi = 0;
+
+ if k-degB > mi
+
+ mi = k-degB;
+
+ end
+
+ ma = degA;
+
+ if k < ma
+
+ ma = k;
+
+ end
+
+ Ck = zeros(rA,cB);
+
+ for i = mi:ma
+
+ Ck = Ck + A(:,i*cA+1:(i+1)*cA)*B(:,(k-i)*cB+1:(k-i+1)*cB);
+
+ end
+
+ C = [C Ck];
+
+ end
+
+ endfunction
+
+ // function [rQ,cQ] = polsize(Q,degQ)
+
+ // FUNCTION polsize TO DETERMINE THE DIMENSIONS
+
+ // OF A POLYNOMIAL MATRIX
+
+ //
+
+ // H. Kwakernaak, August, 1990
+
+
+ function [rQ,cQ] = polsize(Q,degQ)
+
+
+ [rQ,cQ] = size(Q); cQ = cQ/(degQ+1);
+
+ if abs(round(cQ)-cQ) > 1e-6
+
+ error(''polsize: Degree of input inconsistent with number of columns'');
+
+ else
+
+ cQ = round(cQ);
+
+ end
+
+ endfunction
+
+ // function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ // given coefficient matrix in T1, primary redundant row information sel,
+
+ // solves XD + YN = C
+
+
+ // calling order changed on 16 April 2005. Old order:
+
+ // function [B,degB,A,degA,Y,degY,X,degX] = xdync(N,degN,D,degD,C,degC,gap)
+
+
+ function [Y,degY,X,degX,B,degB,A,degA] = xdync(N,degN,D,degD,C,degC,gap)
+
+ if argn(2) == 6
+
+ gap = 1.0e+8;
+
+ end
+
+
+ [F,degF] = rowjoin(D,degD,N,degN);
+
+
+ [Frows,Fbcols] = polsize(F,degF); //Fbcols = block columns
+
+
+ [B,degB,A,degA,S,sel,degT1,Fbcols] = left_prm(N,degN,D,degD,3,gap);
+
+ //if issoln(D,degD,C,degC,B,degB,A,degA)
+
+ [Crows,Ccols] = size(C);
+
+ [Srows,Scols] = size(S);
+
+ S = clean(S);
+
+ S = S(mtlb_logical(sel),:);
+
+ T2 =[];
+
+
+ for i = 1:Crows,
+
+ Saug = seshft(S,C(i,:),0);
+
+ b = cindep(Saug);
+
+ b = move_sci(b,find(sel),Srows);
+
+ T2 =[T2; b];
+
+ end
+
+
+ [X,degX,Y,degY] = colsplit(T2,degT1,Fbcols,Frows-Fbcols);
+
+
+ [X,degX] = clcoef(X,degX);
+
+ [Y,degY] = clcoef(Y,degY);
+
+ Y = clean(Y); X = clean(X);
+
+ endfunction
+
+ // Input arguments are co efficients of numerator and denominator
+
+ // polynomials in ascending powers of z^-1
+
+
+ // Scicos/Xcos blocks need input polynomials
+
+ // with positive powers of z
+
+
+ function [nume,deno] = cosfil_ip(num,den)
+
+
+ [Nn,Nd] = polyno(num,''z'');
+
+ [Dn,Dd] = polyno(den,''z'');
+
+ nume = Nn*Dd;
+
+ deno = Nd*Dn;
+
+
+ endfunction;
+
+
+ // Updated(1-8-07)
+
+ // Operations:
+
+ // Polynomial definition
+
+ // Flipping of coefficients
+
+ // Variables ------- passed as input argument (either ''s'' or ''z'')
+
+ // Both num and den are used mostly used in scicos files,
+
+ // to get rid of negative powers of z
+
+
+ // Polynomials with powers of s need to
+
+ // be flipped only
+
+
+ function [polynu,polyde] = polyno(zc,a)
+
+ zc = clean(zc);
+
+ polynu = poly(zc(length(zc):-1:1),a,''coeff'');
+
+ if a == ''z''
+
+ polyde = %z^(length(zc) - 1);
+
+ else
+
+ polyde = 1;
+
+ end
+
+
+ // Scicos(4.1) Filter block shouldn''t have constant/constant
+
+ if type(polynu)==1 & type(polyde)==1
+
+ if a == ''z''
+
+ polynu = %z; polyde = %z;
+
+ else
+
+ polynu = %s; polyde = %s;
+
+ end;
+
+ end;
+
+
+ endfunction
+
+ // Operating conditions
+
+ M = 0.05; L = 0.01; R = 1; K = 0.0001; g = 9.81;
+
+
+ // Equilibrium conditions
+
+ hs = 0.01; is = sqrt(M*g*hs/K);
+
+
+ // State space matrices
+
+ a21 = K*is^2/M/hs^2; a23 = - 2*K*is/M/hs; a33 = - R/L;
+
+ b3 = 1/L;
+
+ a1 = [0 1 0; a21 0 a23; 0 0 a33];
+
+ b1 = [0; 0; b3]; c1 = [1 0 0]; d1 = 0;
+
+
+ // Transfer functions
+
+ G = syslin(''c'',a1,b1,c1,d1); Ts = 0.01; [B,A,k] = myc2d(G,Ts);
+
+
+ // Transient specifications
+
+ rise = 0.1; epsilon = 0.05;
+
+ phi = desired(Ts,rise,epsilon);
+
+
+ // Controller design
+
+ Delta = [1 -1]; //internal model of step used
+
+ [Rc,Sc,Tc,gamm] = pp_im(B,A,k,phi,Delta);
+
+
+ // simulation parameters for c_ss_cl.xcos
+
+ st = 0.0001; //desired change in h, in m.
+
+ t_init = 0; // simulation start time
+
+ t_final = 0.5; //simulation end time
+
+ xInitial = [0 0 0];
+
+ N = 1; C = 0; D = 1; N_var = 0;
+
+
+ [Tcp1,Tcp2] = cosfil_ip(Tc,1); // Tc/1
+
+ [Np,Rcp] = cosfil_ip(N,Rc); // 1/Rc
+
+ [Scp1,Scp2] = cosfil_ip(Sc,1); // Sc/1
+
+ [Cp,Dp] = cosfil_ip(C,D); // C/D'
- model: saveAPI.gallery
- pk: 664
+ pk: 43
fields:
save_id: gallery42
name: ex10_10
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 10) Sinusoidal Steady state Analysis, 10.10) Superposition Source Transformations
and Thevenin theorem'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="1.0" title="ex10_10"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -72053,15 +94005,16 @@
x="760.0" y="120.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="7a2a91ff:134d8462990:-7b80" parent="7a2a91ff:134d8462990:-7b7f"/></XcosDiagram>
media: gallery42.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 665
+ pk: 44
fields:
save_id: gallery43
name: ex10_11
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 10) Sinusoidal Steady state Analysis, 10.11) Superposition Source Transformations
and Thevenin theorem'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex10_11"><!--Xcos - 1.0 - scilab-5.5.2 -
@@ -73014,15 +94967,16 @@
x="910.0" y="230.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="7a2a91ff:134d8462990:-7955" parent="7a2a91ff:134d8462990:-7954"/></XcosDiagram>
media: gallery43.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 666
+ pk: 45
fields:
save_id: gallery44
name: ex10_1
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 10) Sinusoidal Steady state Analysis, 10.1) Forced Response to sinusoidal
functions'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="ex10_1"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -73743,14 +95697,15 @@
x="760.0" y="170.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-1fad1256:134d7ff92c3:-7ffe" parent="-1fad1256:134d7ff92c3:-7ffd"/></XcosDiagram>
media: gallery44.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 667
+ pk: 46
fields:
save_id: gallery45
name: ex10_6
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 10) Sinusoidal Steady state Analysis, 10.6) Impedance'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="ex10_6"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -74343,14 +96298,15 @@
scilabClass=""><mxPoint x="400.0" y="90.0"/></Array></mxGeometry></ImplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="-1fad1256:134d7ff92c3:-7ef9" parent="-1fad1256:134d7ff92c3:-7ef8"/></XcosDiagram>
media: gallery45.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 668
+ pk: 47
fields:
save_id: gallery46
name: ex10_7
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 10) Sinusoidal Steady state Analysis, 10.7) Nodal and Mesh analysis'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="1.0" title="ex10_7"><!--Xcos - 1.0 - scilab-5.5.2 - 20200302--><mxGraphModel
@@ -75277,14 +97233,15 @@
as="defaultParent" id="-1fad1256:134d7ff92c3:-7e4a" parent="-1fad1256:134d7ff92c3:-7e49"/><mxPoint
as="origin" x="-10.0"/></XcosDiagram>
media: gallery46.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 669
+ pk: 48
fields:
save_id: gallery47
name: ex10_8
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 10) Sinusoidal Steady state Analysis, 10.8) Nodal and Mesh analysis'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.1" title="ex10_8"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -76388,15 +98345,16 @@
scilabClass=""><mxPoint x="230.0" y="250.0"/></Array></mxGeometry></ImplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="7a2a91ff:134d8462990:-7ffe" parent="7a2a91ff:134d8462990:-7ffd"/></XcosDiagram>
media: gallery47.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 670
+ pk: 49
fields:
save_id: gallery48
name: ex10_9
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 10) Sinusoidal Steady state Analysis, 10.9) Superposition Source Transformations
and Thevenin theorem'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="1.0" title="ex10_9"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -77639,14 +99597,15 @@
x="130.0" y="180.0"/><Array as="points" scilabClass=""><mxPoint x="130.0" y="240.0"/></Array></mxGeometry></ImplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="7a2a91ff:134d8462990:-7e88" parent="7a2a91ff:134d8462990:-7e87"/></XcosDiagram>
media: gallery48.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 671
+ pk: 50
fields:
save_id: gallery49
name: ex12_1
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 12) Polyphase Circuits, 12.1) Single phase three wire systems'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="1.0" title="ex12_1"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -78501,14 +100460,15 @@
y="80.0"/><mxPoint x="580.0" y="80.0"/></Array></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-10514b51:134e53d5ed9:-7ffe" parent="-10514b51:134e53d5ed9:-7ffd"/></XcosDiagram>
media: gallery49.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 672
+ pk: 51
fields:
save_id: gallery50
name: ex13_7
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 13) Magnetically coupled circuits, 13.7) The Ideal Transformer'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex13_7"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -79117,14 +101077,15 @@
scilabClass=""><mxPoint x="350.0" y="80.0"/></Array></mxGeometry></ImplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="26015439:134e2b4e9d8:-7fd9" parent="26015439:134e2b4e9d8:-7fd8"/></XcosDiagram>
media: gallery50.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 673
+ pk: 52
fields:
save_id: gallery51
name: ex17_4
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 17) Two Port Networks, 17.4) Admittance parameters'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex17_4"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -80505,15 +102466,16 @@
x="930.0" y="260.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-536a7494:134d5b6a3e7:-7ffa" parent="-536a7494:134d5b6a3e7:-7ff9"/></XcosDiagram>
media: gallery51.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 674
+ pk: 53
fields:
save_id: gallery52
name: ex18_2
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 18) Fourier Circuit Analysis, 18.2) Complete Response to periodic Forcing
Functions'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="6.5" title="ex18_2"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -81264,15 +103226,16 @@
scilabClass=""><mxPoint x="410.0" y="150.0"/></Array></mxGeometry></ImplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="f4a86ca:134efd7fc02:-7ffe" parent="f4a86ca:134efd7fc02:-7ffd"/></XcosDiagram>
media: gallery52.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 675
+ pk: 54
fields:
save_id: gallery53
name: ex18_8
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 18) Fourier Circuit Analysis, 18.8) The physical significance of system
function'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0" title="ex18_8"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -81811,14 +103774,15 @@
x="220.0" y="110.0"/></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="f4a86ca:134efd7fc02:-7e66" parent="f4a86ca:134efd7fc02:-7e65"/></XcosDiagram>
media: gallery53.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 676
+ pk: 55
fields:
save_id: gallery54
name: ex3_11
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 3) Voltage and Current laws, 3.11) Resistors in series and parallel'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex3_11"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -82420,14 +104384,15 @@
scilabClass=""><mxPoint x="70.0" y="110.0"/></Array></mxGeometry></ImplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="-3b708aba:134ce795dea:-8000" parent="-3b708aba:134ce795dea:-7fff"/></XcosDiagram>
media: gallery54.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 677
+ pk: 56
fields:
save_id: gallery55
name: ex3_13
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 3) Voltage and Current laws, 3.13) Voltage and Current division'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex3_13"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -83017,14 +104982,15 @@
x="510.0" y="170.0"/></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="73523f48:134cd91c16f:-7c19" parent="73523f48:134cd91c16f:-7c18"/></XcosDiagram>
media: gallery55.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 678
+ pk: 57
fields:
save_id: gallery56
name: ex3_14
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 3) Voltage and Current laws, 3.14) Voltage and Current division'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex3_14"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -83584,14 +105550,15 @@
as="points" scilabClass=""><mxPoint x="340.0" y="100.0"/></Array></mxGeometry></ImplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="73523f48:134cd91c16f:-7cca" parent="73523f48:134cd91c16f:-7cc9"/></XcosDiagram>
media: gallery56.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 679
+ pk: 58
fields:
save_id: gallery57
name: ex3_1
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 3) Voltage and Current laws, 3.1) Kirchoff current law'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex3_1"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -84218,14 +106185,15 @@
as="geometry" height="40.0" width="40.0" x="230.0" y="260.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-3721b5e:1319cfae9ac:-8000" parent="-3721b5e:1319cfae9ac:-7fff"/></XcosDiagram>
media: gallery57.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 680
+ pk: 59
fields:
save_id: gallery58
name: ex3_2
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 3) Voltage and Current laws, 3.2) Kirchoff voltage law'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex3_2"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -84767,14 +106735,15 @@
x="380.0" y="110.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-3721b5e:1319cfae9ac:-7f30" parent="-3721b5e:1319cfae9ac:-7f2f"/></XcosDiagram>
media: gallery58.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 681
+ pk: 60
fields:
save_id: gallery59
name: ex3_3
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 3) Voltage and Current laws, 3.3) Kirchoff voltage law'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex3_3"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -85368,14 +107337,15 @@
y="280.0"/></Array></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-16593537:1319d63fbbf:-7f80" parent="-16593537:1319d63fbbf:-7f7f"/></XcosDiagram>
media: gallery59.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 682
+ pk: 61
fields:
save_id: gallery60
name: ex3_4
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 3) Voltage and Current laws, 3.4) Kirchoff voltage law'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex3_4"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -86012,14 +107982,15 @@
x="480.0" y="130.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-5fcba885:134ccedce1f:-8000" parent="-5fcba885:134ccedce1f:-7fff"/></XcosDiagram>
media: gallery60.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 683
+ pk: 62
fields:
save_id: gallery61
name: ex3_5
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 3) Voltage and Current laws, 3.5) The Single Loop Circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex3_5"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -86933,14 +108904,15 @@
x="700.0" y="190.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-5fcba885:134ccedce1f:-7cf6" parent="-5fcba885:134ccedce1f:-7cf5"/></XcosDiagram>
media: gallery61.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 684
+ pk: 63
fields:
save_id: gallery62
name: ex3_6
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 3) Voltage and Current laws, 3.6) The single node pair circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex3_6"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -87810,14 +109782,15 @@
x="800.0" y="150.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-5005d4b1:131a4cd73b3:-7eb8" parent="-5005d4b1:131a4cd73b3:-7eb7"/></XcosDiagram>
media: gallery62.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 685
+ pk: 64
fields:
save_id: gallery63
name: ex3_9
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 3) Voltage and Current laws, 3.9) Series and Parallel connected sources'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex3_9"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -88280,14 +110253,15 @@
x="190.0" y="130.0"/><mxPoint as="targetPoint" x="340.0" y="140.0"/></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="-5005d4b1:131a4cd73b3:-7f84" parent="-5005d4b1:131a4cd73b3:-7f83"/></XcosDiagram>
media: gallery63.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 686
+ pk: 65
fields:
save_id: gallery64
name: ex4_10
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 4) Basic Nodal and Mesh Analysis, 4.10) Mesh analysis'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex4_10"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -88994,14 +110968,15 @@
width="40.0" x="90.0" y="30.0"/></TextBlock></root></mxGraphModel><mxCell as="defaultParent"
id="-5f02711f:131ec3f74c9:-7b98" parent="-5f02711f:131ec3f74c9:-7b97"/></XcosDiagram>
media: gallery64.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 687
+ pk: 66
fields:
save_id: gallery65
name: ex4_11
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 4) Basic Nodal and Mesh Analysis, 4.11) The Supermesh'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex4_11"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -89797,14 +111772,15 @@
as="defaultParent" id="-5f02711f:131ec3f74c9:-7a7c" parent="-5f02711f:131ec3f74c9:-7a7b"/><mxPoint
as="origin" x="-6.0" y="-6.0"/></XcosDiagram>
media: gallery65.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 688
+ pk: 67
fields:
save_id: gallery66
name: ex4_12
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 4) Basic Nodal and Mesh Analysis, 4.12) The Supermesh'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex4_12"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -91144,14 +113120,15 @@
x="580.0" y="150.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="5e6a3066:134dff9ba34:-7ffe" parent="5e6a3066:134dff9ba34:-7ffd"/></XcosDiagram>
media: gallery66.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 689
+ pk: 68
fields:
save_id: gallery67
name: ex4_1
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 4) Basic Nodal and Mesh Analysis, 4.1) Nodal analysis'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex4_1"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -91806,14 +113783,15 @@
width="40.0" x="100.0" y="10.0"/></TextBlock></root></mxGraphModel><mxCell as="defaultParent"
id="-16b82e93:131e810ab25:-8000" parent="-16b82e93:131e810ab25:-7fff"/></XcosDiagram>
media: gallery67.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 690
+ pk: 69
fields:
save_id: gallery68
name: ex4_2
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 4) Basic Nodal and Mesh Analysis, 4.2) Nodal analysis'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex4_2"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -93108,14 +115086,15 @@
width="40.0" x="60.0" y="10.0"/></TextBlock></root></mxGraphModel><mxCell as="defaultParent"
id="-16b82e93:131e810ab25:-7f1e" parent="-16b82e93:131e810ab25:-7f1d"/></XcosDiagram>
media: gallery68.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 691
+ pk: 70
fields:
save_id: gallery69
name: ex4_5
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 4) Basic Nodal and Mesh Analysis, 4.5) The supernode'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex4_5"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -93949,14 +115928,15 @@
width="40.0" x="70.0" y="10.0"/></TextBlock></root></mxGraphModel><mxCell as="defaultParent"
id="-5f02711f:131ec3f74c9:-8000" parent="-5f02711f:131ec3f74c9:-7fff"/></XcosDiagram>
media: gallery69.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 692
+ pk: 71
fields:
save_id: gallery70
name: ex4_6
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 4) Basic Nodal and Mesh Analysis, 4.6) The supernode'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex4_6"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -96016,14 +117996,15 @@
x="720.0" y="230.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="5e6a3066:134dff9ba34:-7e89" parent="5e6a3066:134dff9ba34:-7e88"/></XcosDiagram>
media: gallery70.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 693
+ pk: 72
fields:
save_id: gallery71
name: ex4_7
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 4) Basic Nodal and Mesh Analysis, 4.7) Mesh analysis'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex4_7"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -96726,14 +118707,15 @@
width="40.0" x="50.0" y="10.0"/></TextBlock></root></mxGraphModel><mxCell as="defaultParent"
id="-5f02711f:131ec3f74c9:-7da1" parent="-5f02711f:131ec3f74c9:-7da0"/></XcosDiagram>
media: gallery71.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 694
+ pk: 73
fields:
save_id: gallery72
name: ex4_8
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 4) Basic Nodal and Mesh Analysis, 4.8) Mesh analysis'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex4_8"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -97807,14 +119789,15 @@
width="40.0" x="70.0" y="20.0"/></TextBlock></root></mxGraphModel><mxCell as="defaultParent"
id="-5f02711f:131ec3f74c9:-7c8d" parent="-5f02711f:131ec3f74c9:-7c8c"/></XcosDiagram>
media: gallery72.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 695
+ pk: 74
fields:
save_id: gallery73
name: ex4_9
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 4) Basic Nodal and Mesh Analysis, 4.9) Mesh analysis'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex4_9"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -98467,15 +120450,16 @@
width="40.0" x="70.0" y="20.0"/></TextBlock></root></mxGraphModel><mxCell as="defaultParent"
id="-5f02711f:131ec3f74c9:-7e53" parent="-5f02711f:131ec3f74c9:-7e52"/></XcosDiagram>
media: gallery73.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 696
+ pk: 75
fields:
save_id: gallery74
name: ex6_11
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 6) Network Theorems and useful Circuit Analysis Techniques, 6.11) Thevenin
and Norton Equivalent circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex6_11"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -98977,15 +120961,16 @@
x="320.0" y="100.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="2602728:132d47c9ecc:-8000" parent="2602728:132d47c9ecc:-7fff"/></XcosDiagram>
media: gallery74.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 697
+ pk: 76
fields:
save_id: gallery75
name: ex6_13
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 6) Network Theorems and useful Circuit Analysis Techniques, 6.13) Thevenin
and Norton Equivalent circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex6_13"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -99749,15 +121734,16 @@
x="780.0" y="240.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="2602728:132d47c9ecc:-7f5b" parent="2602728:132d47c9ecc:-7f5a"/></XcosDiagram>
media: gallery75.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 698
+ pk: 77
fields:
save_id: gallery76
name: ex6_14
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 6) Network Theorems and useful Circuit Analysis Techniques, 6.14) Thevenin
and Norton Equivalent circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex6_14"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -100771,15 +122757,16 @@
x="400.0" y="44.0"/><mxPoint as="targetPoint" x="400.0" y="70.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-1f470ada:134d070a228:-7f33" parent="-1f470ada:134d070a228:-7f32"/></XcosDiagram>
media: gallery76.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 699
+ pk: 78
fields:
save_id: gallery77
name: ex6_15
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 6) Network Theorems and useful Circuit Analysis Techniques, 6.15) Thevenin
and Norton Equivalent circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex6_15"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -101321,15 +123308,16 @@
x="370.0" y="124.0"/><mxPoint as="targetPoint" x="370.0" y="150.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-1f470ada:134d070a228:-8000" parent="-1f470ada:134d070a228:-7fff"/></XcosDiagram>
media: gallery77.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 700
+ pk: 79
fields:
save_id: gallery78
name: ex6_16
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 6) Network Theorems and useful Circuit Analysis Techniques, 6.16) Maximum
power transfer'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex6_16"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -102616,15 +124604,16 @@
as="defaultParent" id="6611b517:134eb867750:-7b61" parent="6611b517:134eb867750:-7b60"/><mxPoint
as="origin" x="-2.5"/></XcosDiagram>
media: gallery78.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 701
+ pk: 80
fields:
save_id: gallery79
name: ex6_1
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 6) Network Theorems and useful Circuit Analysis Techniques, 6.1) The
Superposition principle'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex6_1"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -103349,15 +125338,16 @@
as="sourcePoint" x="566.0" y="190.0"/><mxPoint as="targetPoint" x="550.0" y="190.0"/></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="-5872192d:1324f245276:-8000" parent="-5872192d:1324f245276:-7fff"/></XcosDiagram>
media: gallery79.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 702
+ pk: 81
fields:
save_id: gallery80
name: ex6_20
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 6) Network Theorems and useful Circuit Analysis Techniques, 6.20) Compensation
Theorem'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="1.0" title="ex6_20"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -104055,15 +126045,16 @@
x="570.0" y="100.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="6611b517:134eb867750:-7ffe" parent="6611b517:134eb867750:-7ffd"/></XcosDiagram>
media: gallery80.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 703
+ pk: 82
fields:
save_id: gallery81
name: ex6_21
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 6) Network Theorems and useful Circuit Analysis Techniques, 6.21) Compensation
Theorem'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex6_21"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -104879,15 +126870,16 @@
y="180.0"/><mxPoint x="560.0" y="180.0"/></Array></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="6611b517:134eb867750:-7ec6" parent="6611b517:134eb867750:-7ec5"/></XcosDiagram>
media: gallery81.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 704
+ pk: 83
fields:
save_id: gallery82
name: ex6_23
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 6) Network Theorems and useful Circuit Analysis Techniques, 6.23) Source
Transformations'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex6_23"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -105436,15 +127428,16 @@
x="490.0" y="130.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="6611b517:134eb867750:-7be7" parent="6611b517:134eb867750:-7be6"/></XcosDiagram>
media: gallery82.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 705
+ pk: 84
fields:
save_id: gallery83
name: ex6_24
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 6) Network Theorems and useful Circuit Analysis Techniques, 6.24) Source
Transformations'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex6_24"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -106624,15 +128617,16 @@
scilabClass="ScilabList"><mxPoint x="210.0" y="200.0"/><mxPoint x="210.0" y="120.0"/></Array></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="6611b517:134eb867750:-7d3e" parent="6611b517:134eb867750:-7d3d"/></XcosDiagram>
media: gallery83.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 706
+ pk: 85
fields:
save_id: gallery84
name: ex6_3
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 6) Network Theorems and useful Circuit Analysis Techniques, 6.3) The
Superposition principle'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex6_3"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -107489,15 +129483,16 @@
x="710.0" y="44.0"/><mxPoint as="targetPoint" x="710.0" y="60.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-5872192d:1324f245276:-7ee4" parent="-5872192d:1324f245276:-7ee3"/></XcosDiagram>
media: gallery84.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 707
+ pk: 86
fields:
save_id: gallery85
name: ex6_4
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 6) Network Theorems and useful Circuit Analysis Techniques, 6.4) The
Superposition principle'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex6_4"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -108314,15 +130309,16 @@
y="120.0"/></Array></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-5872192d:1324f245276:-7d2f" parent="-5872192d:1324f245276:-7d2e"/></XcosDiagram>
media: gallery85.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 708
+ pk: 87
fields:
save_id: gallery86
name: ex6_5
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 6) Network Theorems and useful Circuit Analysis Techniques, 6.5) The
Superposition principle'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex6_5"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -108996,15 +130992,16 @@
x="570.0" y="70.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-5872192d:1324f245276:-7c11" parent="-5872192d:1324f245276:-7c10"/></XcosDiagram>
media: gallery86.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 709
+ pk: 88
fields:
save_id: gallery87
name: ex6_6
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 6) Network Theorems and useful Circuit Analysis Techniques, 6.6) The
Superposition principle'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex6_6"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -109867,15 +131864,16 @@
as="geometry" height="8.0" width="8.0" x="16.0" y="40.0"/></ImplicitOutputPort></root></mxGraphModel><mxCell
as="defaultParent" id="-5872192d:1324f245276:-7b3d" parent="-5872192d:1324f245276:-7b3c"/></XcosDiagram>
media: gallery87.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 710
+ pk: 89
fields:
save_id: gallery88
name: ex6_8
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 6) Network Theorems and useful Circuit Analysis Techniques, 6.8) The
Superposition principle'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex6_8"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -110958,14 +132956,15 @@
x="856.0" y="340.0"/><mxPoint as="targetPoint" x="830.0" y="340.0"/></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="-1ed2b2d8:132d4611bb5:-7f3b" parent="-1ed2b2d8:132d4611bb5:-7f3a"/></XcosDiagram>
media: gallery88.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 711
+ pk: 90
fields:
save_id: gallery89
name: ex7_11
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 7) Capacitors and Inductors, 7.11) Modeling Capacitors and Inductors'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="1.0" title="ex7_11"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -111549,14 +133548,15 @@
x="500.0" y="100.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="3a97bac1:134ed06dad1:-7ffe" parent="3a97bac1:134ed06dad1:-7ffd"/></XcosDiagram>
media: gallery89.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 712
+ pk: 91
fields:
save_id: gallery90
name: ex8_10
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 8) Basic RL and RC circuits, 8.10) Driven RC circuits'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0" title="ex8_10"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -112700,14 +134700,15 @@
as="defaultParent" id="75a896ca:134d365eac8:-7b7b" parent="75a896ca:134d365eac8:-7b7a"/><mxPoint
as="origin" y="-6.0"/></XcosDiagram>
media: gallery90.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 713
+ pk: 92
fields:
save_id: gallery91
name: ex8_11
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 8) Basic RL and RC circuits, 8.11) Driven RC circuits'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.01" title="ex8_11"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -113316,14 +135317,15 @@
x="340.0" y="186.0"/><mxPoint as="targetPoint" x="340.0" y="120.0"/></mxGeometry></ImplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="-5e5c20b5:13506c8a689:-8000" parent="-5e5c20b5:13506c8a689:-7fff"/></XcosDiagram>
media: gallery91.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 714
+ pk: 93
fields:
save_id: gallery92
name: ex8_1
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 8) Basic RL and RC circuits, 8.1) The Source free RL Circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.001" title="ex8_1"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -113814,14 +135816,15 @@
x="470.0" y="150.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="77dd482d:134d2cc3c9e:-7f9a" parent="77dd482d:134d2cc3c9e:-7f99"/></XcosDiagram>
media: gallery92.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 715
+ pk: 94
fields:
save_id: gallery93
name: ex8_2
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 8) Basic RL and RC circuits, 8.2) The Source free RL Circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="1.0" title="ex8_2"><!--Xcos - 1.0 - scilab-5.5.2 - 20200302--><mxGraphModel
@@ -114503,14 +136506,15 @@
y="360.0"/><mxPoint x="70.0" y="360.0"/><mxPoint x="70.0" y="230.0"/></Array></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="-29171e7b:13894ec359c:-8000" parent="-29171e7b:13894ec359c:-7fff"/></XcosDiagram>
media: gallery93.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 716
+ pk: 95
fields:
save_id: gallery94
name: ex8_3
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 8) Basic RL and RC circuits, 8.3) The Source free RC Circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0E-4" title="ex8_3"><!--Xcos - 1.0 - scilab-5.5.2 -
@@ -115038,14 +137042,15 @@
x="420.0" y="120.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-7550ec02:134d2eb8d96:-7d27" parent="-7550ec02:134d2eb8d96:-7d26"/></XcosDiagram>
media: gallery94.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 717
+ pk: 96
fields:
save_id: gallery95
name: ex8_4
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 8) Basic RL and RC circuits, 8.4) A more General Perspective'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="1.0E-4" title="ex8_4"><!--Xcos - 1.0 - scilab-5.5.2 -
@@ -115783,14 +137788,15 @@
x="114.0" y="170.0"/><mxPoint as="targetPoint" x="170.0" y="170.0"/></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="-7550ec02:134d2eb8d96:-7c3f" parent="-7550ec02:134d2eb8d96:-7c3e"/></XcosDiagram>
media: gallery95.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 718
+ pk: 97
fields:
save_id: gallery96
name: ex8_8
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 8) Basic RL and RC circuits, 8.8) Natural and Forced Response'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex8_8"><!--Xcos - 1.0 - scilab-5.5.2 - 20200302--><mxGraphModel
@@ -116447,14 +138453,15 @@
x="560.0" y="120.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="75a896ca:134d365eac8:-7eb8" parent="75a896ca:134d365eac8:-7eb7"/></XcosDiagram>
media: gallery96.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 719
+ pk: 98
fields:
save_id: gallery97
name: ex9_2
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 9) The RLC Circuit, 9.2) The Overdamped parallel circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.001" title="ex9_2"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -116991,14 +138998,15 @@
x="470.0" y="90.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="2adc5834:134f2773fd2:-7ffe" parent="2adc5834:134f2773fd2:-7ffd"/></XcosDiagram>
media: gallery97.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 720
+ pk: 99
fields:
save_id: gallery98
name: ex9_3
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 9) The RLC Circuit, 9.3) The Overdamped parallel circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.001" title="ex9_3"><!--Xcos - 1.0 - scilab-5.5.2 - 20200302--><mxGraphModel
@@ -117823,14 +139831,15 @@
x="850.0" y="180.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-67b45fed:134f41509ef:-7ffe" parent="-67b45fed:134f41509ef:-7ffd"/></XcosDiagram>
media: gallery98.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 721
+ pk: 100
fields:
save_id: gallery99
name: ex9_6
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 9) The RLC Circuit, 9.6) The Underdamped parallel RLC circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0" title="ex9_6"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -118327,14 +140336,15 @@
y="130.0"/></Array></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-7cfb447d:134ed64a89d:-7ffe" parent="-7cfb447d:134ed64a89d:-7ffd"/></XcosDiagram>
media: gallery99.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 722
+ pk: 101
fields:
save_id: gallery100
name: ex9_7
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 9) The RLC Circuit, 9.7) The Source free series RLC Circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.001" title="ex9_7"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -118909,14 +140919,15 @@
x="440.0" y="110.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-3d3fe24b:134fb5bd9e1:-7d4a" parent="-3d3fe24b:134fb5bd9e1:-7d49"/></XcosDiagram>
media: gallery100.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 723
+ pk: 102
fields:
save_id: gallery101
name: ex9_8
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 9) The RLC Circuit, 9.8) The Source free series RLC Circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0" title="ex9_8"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -119611,14 +141622,15 @@
x="500.0" y="70.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="1f781c6f:13506286c0b:-7ffe" parent="1f781c6f:13506286c0b:-7ffd"/></XcosDiagram>
media: gallery101.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 724
+ pk: 103
fields:
save_id: gallery102
name: ex9_9
description: 'Engineering Circuit Analysis (Author: W. Hayt, J. Kemmerly And S.
Durbin), 9) The RLC Circuit, 9.9) The Complete response of RLC circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 215
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="ex9_9"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -120272,14 +142284,15 @@
x="600.0" y="180.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="1f781c6f:13506286c0b:-7d57" parent="1f781c6f:13506286c0b:-7d56"/></XcosDiagram>
media: gallery102.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 725
+ pk: 104
fields:
save_id: gallery103
name: Ex6_23
description: 'Electrical Machines (Author: R. K. Srivastava), 6) Synchronous Machines,
6.23) To find maximum value of power angle and maximum value of overshoot'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 2777
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
title="Ex6_23"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406 2040--><Array as="context"
@@ -120795,14 +142808,116 @@
as="geometry" height="40.0" width="40.0" x="440.0" y="310.0"/></BasicBlock></root></mxGraphModel><mxCell
as="defaultParent" id="6521d368:1479034e794:-7fa0" parent="6521d368:1479034e794:-7f9f"/></XcosDiagram>
media: gallery103.png
+ script_dump: '
+
+ // ELECTRICAL MACHINES
+
+ // R.K.Srivastava
+
+ // First Impression 2011
+
+ // CENGAGE LEARNING INDIA PVT. LTD
+
+ // CHAPTER : 6 : SYNCHRONOUS MACHINES
+
+
+ // EXAMPLE : 6.23
+
+
+ // GIVEN DATA
+
+
+ p = 4; // Number of the poles in the Alternator
+
+ f = 50; // Frequency in Hertz
+
+ pkw = 500; // Alternator delivering load in kilo-watts
+
+ pkwinc = 1000; // Generator increases its share of the common
+ elictrical in kilo-watts
+
+ Kj = 1.5; // Inertia acceleration coefficient for the
+ combined prime mover-alternator in N-m/elec deg/second square
+
+ Kd = 12; // Damping torque coefficient in N-m/elec deg/second
+
+ delta1 = 9; // Initial value of the Power angle in degree
+
+
+
+ // CALCULATIONS
+
+
+ delta2 = (pkwinc/pkw)*delta1; // Final value (maximum
+ value) of the Power angle in degree (considering Linear variation)
+
+ ws = (4*%pi*f)/p; // Rotational speed
+ in Radians per second
+
+ Ts = (pkw*1000)/ws; // Synchornizing
+ torque at 500kW in N-m
+
+ Ks = Ts/delta1; // Synchornizing
+ torque cofficient at 500kW in N-m/elec-deg
+
+ // Laplace transform of the swing Equation can be written as :- s^2 + ((Kd/Kj)*s)
+ + (Ks/Kj) = 0, s^2 + (12/1.5)s + (353.86/1.5) = 0 and compring with the standard
+ equation s^2 + s(2*zeta*Wn) + Wn^2 = 0 we get:- mentined below (refer page
+ no. 454 and 455)
+
+ Wn = sqrt(Ks/Kj); // Natural frequency
+ of oscillations in Radians per second
+
+ fn = Wn/(2*%pi); // Frequency of
+ natural oscillations in Hertz
+
+ zeta = (1*Kd)/(2*Wn*Kj); // Damping ratio
+
+ Wd = Wn*(sqrt(1-zeta^2)); // Frequency of
+ damped oscillations in radians/s
+
+ fd = Wd/(2*%pi); // Frequency of
+ damped oscillations in Hertz
+
+ ts = 5/(zeta*Wn); // Settling time
+ in second
+
+ deltamax = delta1 + 1.42*(delta2-delta1); // The maximum overshoot
+ for damping ratio of 0.2604 is about 42% the maximum appoximate value of the
+ overshoot in terms of 1% tolearance band in Electrical degree
+
+
+
+ // DISPLAY RESULTS
+
+
+ disp("EXAMPLE : 6.23: SOLUTION :-");
+
+ printf("\n (a.1) Final value (maximum value) of the Power angle (considering
+ Linear variation), delta2 = %.f degree \n",delta2)
+
+ printf("\n (a.2) Natural frequency of oscillations, Ns = %.2f radians/s \n",Wn)
+
+ printf("\n (a.3) Damping ratio, zeta = %.4f \n",zeta)
+
+ printf("\n (a.4) Frequency of damped oscillations, Wd = %.2f radians/s \n",Wd)
+
+ printf("\n (a.5) Settling time, ts = %.2f seconds \n",ts)
+
+ printf("\n (b) The maximum overshoot for damping ratio of 0.2604 is about
+ 42 percent the maximum appoximate value of the overshoot in terms of 1 percent
+ tolearance band is, deltamax = %.2f degree \n",deltamax)
+
+ printf("\n\n FOR CASE (C) CANNOT BE DO IT IN THIS BECAUSE AS IT REQUIRES MATLAB
+ SIMULINK \n")'
- model: saveAPI.gallery
- pk: 726
+ pk: 105
fields:
save_id: gallery104
name: eg12_2
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 12) Simplifying
- logical functions, 12.2) Prove the given theorem'
- save_time: 2025-01-23 16:04:57+00:00
+ logical functions, 12.2) Prove the given theoram'
+ save_time: 2025-03-17 15:49:08+00:00
book: 293
data_dump: '<?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="4.0" title="eg12_2"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -122869,15 +144984,16 @@
id="47283b12:1341c9b3c8b:-78f7" parent="47283b12:1341c9b3c8b:-78f6"/><mxPoint
as="origin" x="-10.0"/></XcosDiagram>'
media: gallery104.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 727
+ pk: 106
fields:
save_id: gallery105
name: eg12_3a
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 12) Simplifying
logical functions, 12.3.a) Design a digital logic circuit that provides logic
1 whenever majority votes yes'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="8.0" title="eg12_3a"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -125999,14 +148115,15 @@
as="geometry" height="40.0" width="40.0" x="520.0" y="200.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="47283b12:1341c9b3c8b:-8000" parent="47283b12:1341c9b3c8b:-7fff"/></XcosDiagram>
media: gallery105.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 728
+ pk: 107
fields:
save_id: gallery106
name: eg12_3b
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 12) Simplifying
logical functions, 12.3.b) Modify part A so that only NAND gates are used'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:08+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="8.0" title="eg12_3b"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -129126,14 +151243,15 @@
height="40.0" width="40.0" x="50.0" y="330.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="47283b12:1341c9b3c8b:-7c5b" parent="47283b12:1341c9b3c8b:-7c5a"/></XcosDiagram>
media: gallery106.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 729
+ pk: 108
fields:
save_id: gallery107
name: eg2_10
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 2) The
circuit elements, 2.10) Design an opamp circuit solution of the given equation'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="eg2_10"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -131666,14 +153784,15 @@
x="190.0" y="180.0"/><mxPoint as="targetPoint" x="310.0" y="180.0"/></mxGeometry></ImplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="200893ff:13428736452:-8000" parent="200893ff:13428736452:-7fff"/></XcosDiagram>
media: gallery107.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 730
+ pk: 109
fields:
save_id: gallery108
name: eg3_10
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 3) Elementary
network theory, 3.10) Find the value of the node pair voltages V1 and V2'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="eg3_10"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -132519,14 +154638,15 @@
height="40.0" width="40.0" x="490.0" y="180.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-108078b6:1345b8f2778:-7b1d" parent="-108078b6:1345b8f2778:-7b1c"/></XcosDiagram>
media: gallery108.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 731
+ pk: 110
fields:
save_id: gallery109
name: eg3_11
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 3) Elementary
network theory, 3.11) Find the branch current flowing through R2'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 293
data_dump: '<?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="eg3_11"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -133145,14 +155265,15 @@
height="40.0" width="40.0" x="110.0" y="430.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-108078b6:1345b8f2778:-79f9" parent="-108078b6:1345b8f2778:-79f8"/></XcosDiagram>'
media: gallery109.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 732
+ pk: 111
fields:
save_id: gallery110
name: eg3_14
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 3) Elementary
network theory, 3.14) Find the value of the output voltage'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="eg3_14"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -133758,14 +155879,15 @@
x="460.0" y="190.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-108078b6:1345b8f2778:-794d" parent="-108078b6:1345b8f2778:-794c"/></XcosDiagram>
media: gallery110.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 733
+ pk: 112
fields:
save_id: gallery111
name: eg3_15
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 3) Elementary
network theory, 3.15) Find the current delivered to the source by the network'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="eg3_15"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -134438,14 +156560,15 @@
as="geometry" height="40.0" width="40.0" x="270.0" y="280.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-108078b6:1345b8f2778:-78b9" parent="-108078b6:1345b8f2778:-78b8"/></XcosDiagram>
media: gallery111.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 734
+ pk: 113
fields:
save_id: gallery112
name: eg3_5
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 3) Elementary
network theory, 3.5) Determine the current which flows through R2'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="eg3_5"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -135092,14 +157215,15 @@
as="geometry" height="8.0" width="8.0" x="16.0" y="40.0"/></ImplicitOutputPort></root></mxGraphModel><mxCell
as="defaultParent" id="-108078b6:1345b8f2778:-8000" parent="-108078b6:1345b8f2778:-7fff"/></XcosDiagram>
media: gallery112.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 735
+ pk: 114
fields:
save_id: gallery113
name: eg3_6
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 3) Elementary
network theory, 3.6) Find the power dissipation in R1'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="eg3_6"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -135832,14 +157956,15 @@
as="geometry" height="40.0" width="40.0" x="560.0" y="70.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-108078b6:1345b8f2778:-7edc" parent="-108078b6:1345b8f2778:-7edb"/></XcosDiagram>
media: gallery113.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 736
+ pk: 115
fields:
save_id: gallery114
name: eg3_7
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 3) Elementary
network theory, 3.7) Find the current which flows through R2'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="eg3_7"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -136766,15 +158891,16 @@
width="40.0" x="380.0" y="280.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-108078b6:1345b8f2778:-7e22" parent="-108078b6:1345b8f2778:-7e21"/></XcosDiagram>
media: gallery114.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 737
+ pk: 116
fields:
save_id: gallery115
name: eg3_9
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 3) Elementary
network theory, 3.9) Find the magnitude and direction of each of the branch
currents'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="eg3_9"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -137492,15 +159618,16 @@
as="geometry" height="40.0" width="40.0" x="200.0" y="380.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-108078b6:1345b8f2778:-7bff" parent="-108078b6:1345b8f2778:-7bfe"/></XcosDiagram>
media: gallery115.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 738
+ pk: 117
fields:
save_id: gallery116
name: eg5_1
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 5) Circuit
dynamics and forced responses, 5.1) Find the expression for the current flowing
through the circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="20.0" title="eg5_1"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -138352,15 +160479,16 @@
x="120.0" y="20.0"/></TextBlock></root></mxGraphModel><mxCell as="defaultParent"
id="7ce57742:133f8596f12:-7f12" parent="7ce57742:133f8596f12:-7f11"/></XcosDiagram>
media: gallery116.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 739
+ pk: 118
fields:
save_id: gallery117
name: eg5_2
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 5) Circuit
dynamics and forced responses, 5.2) Find the expression for the current flowing
through the circuit and the total energy dissipated in the resistor'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="eg5_2"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -139101,15 +161229,32 @@
x="344.0" y="140.0"/><mxPoint as="targetPoint" x="420.0" y="140.0"/></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="4c3b265:134192dde3e:-7ed0" parent="4c3b265:134192dde3e:-7ecf"/></XcosDiagram>
media: gallery117.png
+ script_dump: 'C = 10*10^-6 ; //capacitance(in farads)
+
+ R = 0.2*10^6; //resistance (in ohms)
+
+ Vi = 40; //initial voltage of the capacitor (in volts)
+
+ Wc = (1/2)*C*Vi^2; //energy stored in the capacitor
+
+ //current flowing in circuit as a function of time i(t) = 2*10^-4*exp(-t/2)
+
+ //power dissipated in the resistor = R*i^2
+
+ Wr = integrate(''R*4*10^-8*exp(-t)'',''t'',0,100)
+
+ disp(Wc,"energy stored in the capacitor(in Joules) = ")
+
+ disp(Wr,"energy dissipated in the resistor(in Joules) = ")'
- model: saveAPI.gallery
- pk: 740
+ pk: 119
fields:
save_id: gallery118
name: eg5_3
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 5) Circuit
dynamics and forced responses, 5.3) Determine the voltage which appears across
each capacitor at steady state'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="50.0" title="eg5_3"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -140006,15 +162151,16 @@
height="40.0" width="40.0" x="260.0" y="390.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="4c3b265:134192dde3e:-7e2e" parent="4c3b265:134192dde3e:-7e2d"/></XcosDiagram>
media: gallery118.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 741
+ pk: 120
fields:
save_id: gallery119
name: eg5_5
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 5) Circuit
dynamics and forced responses, 5.5) Find the complete solution for the charge
on the capacitor and show a plot of the response'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.5" title="eg5_5"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -140927,15 +163073,16 @@
as="geometry" height="8.0" width="8.0" x="16.0" y="-8.0"/></ImplicitInputPort></root></mxGraphModel><mxCell
as="defaultParent" id="4c3b265:134192dde3e:-7d26" parent="4c3b265:134192dde3e:-7d25"/></XcosDiagram>
media: gallery119.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 742
+ pk: 121
fields:
save_id: gallery120
name: eg5_6
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 5) Circuit
dynamics and forced responses, 5.6) Describe the dynamic behaviour of the given
circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0" title="eg5_6"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -141790,15 +163937,16 @@
width="40.0" x="230.0" y="360.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="4c3b265:134192dde3e:-7bc3" parent="4c3b265:134192dde3e:-7bc2"/></XcosDiagram>
media: gallery120.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 743
+ pk: 122
fields:
save_id: gallery121
name: eg5_7
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 5) Circuit
dynamics and forced responses, 5.7) Obtain the critically damped response for
the circuit'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0" title="eg5_7"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -142650,15 +164798,16 @@
as="geometry" height="8.0" width="8.0" x="16.0" y="40.0"/></ImplicitOutputPort></root></mxGraphModel><mxCell
as="defaultParent" id="774ef901:13456c50b60:-7ee1" parent="774ef901:13456c50b60:-7ee0"/></XcosDiagram>
media: gallery121.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 744
+ pk: 123
fields:
save_id: gallery122
name: eg5_8
description: 'Electrical Engineering Fundamentals (Author: V. Del Toro), 5) Circuit
dynamics and forced responses, 5.8) Repeat the previous example for the case
where the resistance R is changed'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 293
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0" title="eg5_8"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -143511,15 +165660,16 @@
as="geometry" height="8.0" width="8.0" x="16.0" y="40.0"/></ImplicitOutputPort></root></mxGraphModel><mxCell
as="defaultParent" id="774ef901:13456c50b60:-7e9f" parent="774ef901:13456c50b60:-7e9e"/></XcosDiagram>
media: gallery122.png
+ script_dump: ''
- model: saveAPI.gallery
- pk: 745
+ pk: 124
fields:
save_id: gallery123
name: Ex6_14_model
description: 'Feedback Control of Dynamic Systems (Author: G. F. Franklin, J.
D. Powell and A. Emami-Naeini), 6) The Frequency Response Design Method, 6.14)
Lead compensation for DC motor'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3432
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0" title="Ex6_14_model"><!--Xcos - 1.0 - scilab-5.5.2
@@ -144742,15 +166892,28 @@
y="120.0"/></Array></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-2dd55334:14dcbdd0183:-7fd3" parent="-2dd55334:14dcbdd0183:-7fd2"/></XcosDiagram>
media: gallery123.png
+ script_dump: '//Example 6.14
+
+ //Lead compensation for DC motor.
+
+
+ // the required value
+
+ // for step response, set sw to 2
+
+ // for ramp response, set sw to 0
+
+
+ sw=2'
- model: saveAPI.gallery
- pk: 746
+ pk: 125
fields:
save_id: gallery124
name: Ex7_32_model
description: 'Feedback Control of Dynamic Systems (Author: G. F. Franklin, J.
D. Powell and A. Emami-Naeini), 7) State Space Design, 7.32) Redesign of the
Dc servo compensator using SRL'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3432
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0" title="Ex7_32_model"><!--Xcos - 1.0 - scilab-5.5.2
@@ -145972,15 +168135,198 @@
as="defaultParent" id="-2dd55334:14dcbdd0183:-7fd3" parent="-2dd55334:14dcbdd0183:-7fd2"/><mxPoint
as="origin" y="-2.0"/></XcosDiagram>
media: gallery124.png
+ script_dump: '//------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+
+ //A function written by Deepti Khimani.
+
+ //Usage:-
+
+ //p=zpk_dk(sl)
+
+ //[p, z]=zpk_dk(sl)
+
+ //[p, z, k]=zpk_dk(sl)
+
+ //p:- Poles of the system
+
+ //z:- zeros of the system
+
+ //k:- DC gain of the system
+
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+
+
+ function[pl,zr,k]=zpk_dk(sysmodel)
+
+ [lhs,rhs]=argn(0)
+
+
+ if rhs == 0 then
+
+ disp(["p=zpk_dk(sl)";"[p, z]=zpk_dk(sl)";"[p, z, k]=zpk_dk(sl)"]);
+
+ disp(["p:- Poles of the system";"z:- zeros of the system"]);
+
+ disp("k:- DC gain of the system");
+
+ return;
+
+ end
+
+
+ if typeof(sysmodel)=="rational" then
+
+ sys=tf2ss(sysmodel);
+
+ pl=spec(sys.A);
+
+ zr=trzeros(sys);
+
+ temp1=poly(zr,''s'',''roots'')/poly(pl,''s'',''roots'');
+
+ temp2=sysmodel/temp1;
+
+ temp3=tf2ss(temp2);
+
+ k=temp3.D;
+
+ elseif typeof(sysmodel)=="state-space" then
+
+ pl=spec(sysmodel.A);
+
+ zr=trzeros(sysmodel);
+
+ g=ss2tf(sysmodel);
+
+ temp1=poly(zr,''s'',''roots'')/poly(pl,''s'',''roots'');
+
+ temp2=g/temp1;
+
+ temp3=tf2ss(temp2);
+
+ k=temp3.D
+
+ else
+
+ error("Wrong type of input argument.")
+
+ end
+
+ endfunction
+
+
+ //Example 7.32
+
+ // Redesign of the Dc servo compensator using SRL
+
+
+ // State space representation
+
+ //Transfer function model for DC Servo
+
+ s=poly(0,''s'');
+
+ num=10;
+
+ den=s*(s+2)*(s+8);
+
+ Gs=syslin(''c'',num/den);
+
+
+ // State space representation
+
+ F=[-10 1 0;-16 0 1;0 0 0]
+
+ G=[0 0 10]'';
+
+ H=[1 0 0];
+
+ J=0;
+
+ n=sqrt(length(F));
+
+ //Desired poles for the DC Servo system.
+
+ Pc=[-2+1.56*%i -2-1.56*%i -8.04]
+
+
+
+ // State feedback gain
+
+ K=ppol(F,G,Pc)
+
+ disp(K,''K='',"State feedback gain")
+
+
+ //Estimator - error roots are at
+
+ Pe=[-4+4.49*%i -4-4.49*%i -9.169]
+
+ Lt=ppol(F'',H'',Pe);
+
+ L=clean(Lt'');
+
+ disp(L,''L='',"Observer gain")
+
+ //Error in book, Gain values are different in book.
+
+ //------------------------------------------------------------------
+
+ //Compensator Design
+
+ DK=-K*inv(s*eye(n,n)-F+G*K+L*H)*L;
+
+ DK=syslin(''c'',DK)
+
+ [pl,zr,Kp]=zpk_dk(DK);
+
+ Dc=poly(zr,''s'',''roots'')/poly(pl,''s'',''roots'')
+
+ //------------------------------------------------------------------
+
+ //symmetric root locus
+
+ G_s=horner(Gs,-s);
+
+ evans(Gs*G_s)
+
+ //root locus
+
+ evans(Gs*Dc) //Correct root locus
+
+ //Discrete-time controller
+
+ nc=94.5*conv([7.98 1],[2.52 1])
+
+ dc=conv([59.5348 8.56 1],[10.6 1])
+
+ sysDc=poly(nc,''s'',''coeff'')/poly(dc,''s'',''coeff'');
+
+ sysDc_ss=syslin(''c'',tf2ss(sysDc));
+
+ ts=0.1;
+
+ sysDd=dscr(sysDc_ss,ts)
+
+ Gdz=ss2tf(sysDd);
+
+
+ disp(sysDc,"Continuous-time compensator")
+
+ disp(Gdz,"Discrete-time compensator")'
- model: saveAPI.gallery
- pk: 747
+ pk: 126
fields:
save_id: gallery125
name: Ex7_34_model
description: 'Feedback Control of Dynamic Systems (Author: G. F. Franklin, J.
D. Powell and A. Emami-Naeini), 7) State Space Design, 7.34) Servomechanism
increasing the velocity constant through zero assignment'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3432
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0" title="Ex7_34_model"><!--Xcos - 1.0 - scilab-5.5.2
@@ -147464,15 +169810,238 @@
as="defaultParent" id="-2dd55334:14dcbdd0183:-7fd3" parent="-2dd55334:14dcbdd0183:-7fd2"/><mxPoint
as="origin" y="-12.0"/></XcosDiagram>
media: gallery125.png
+ script_dump: '//Example 7.34
+
+ // Servomechanism, increasing the velocity constant through
+
+ // zero assignment.
+
+
+ // State space representation
+
+ //Transfer function model for DC Servo
+
+ s=poly(0,''s'');
+
+ num=1;
+
+ den=s*(s+1);
+
+ Gs=syslin(''c'',num/den);
+
+
+ // State space representation
+
+ F=[0 1;0 -1]
+
+ G=[0 1]'';
+
+ H=[1 0];
+
+ J=0;
+
+ n=sqrt(length(F));
+
+ //Desired poles for the DC Servo system.
+
+ Pc=[-2 -2]
+
+
+ // State feedback gain
+
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+
+ //A function written by Deepti Khimani.
+
+ //Usage:-
+
+ //[K, lambda]=acker_dk(a, b, pl)
+
+ //K=acker_dk(a, b, pl)
+
+ //a:- System matrix.
+
+ //b:- input matrix.
+
+ //p:- Desired poles.
+
+ //K:-State feedback gain for the control law u=-Kx.
+
+ //lambda:- Eigen values of (a-b*k)
+
+ //------------------------------------------------------------------
+
+ //------------------------------------------------------------------
+
+
+ function [K, lambda]=acker_dk(a, b, pl)
+
+ [lhs,rhs]=argn(0)
+
+
+ if rhs == 0 then
+
+ disp(["K=acker_dk(a, b, pl)";"[K, lambda]=acker_dk(a, b, pl)"]);
+
+ disp(["a:- System matrix";"b:- input matrix";"p:- Desired poles"]);
+
+ disp(["K:-State feedback gain for the control law u=-Kx";...
+
+ "lambda:- Eigen values of (a-b*k)"]);
+
+ return;
+
+ end
+
+ [ra ca]=size(a);
+
+ [rb cb]=size(b);
+
+ l=length(pl);
+
+
+ CO=cont_mat(a,b);
+
+
+ if ra~=l then
+
+ error(["Dimension error:";"number of desired poles must equal...
+
+ to order of the system"]);
+
+ elseif ra~=ca then
+
+ error(["Dimension error:";"system matrix should be...
+
+ a sqaure matrix"]);
+
+ elseif rb~=ra then
+
+ error (["Dimension error:","Input matrix should have...
+
+ as many rows as a system matrix."]);
+
+ elseif rank(CO)<ra then
+
+ error("system is not controllable");
+
+ end
+
+ //------------------------------------------------------------------
+
+ //controllable canonical form
+
+ [Ac,Bc,T,ind]=canon(a,b);
+
+
+ //CO=zeros(ra,cb);
+
+ for i=1:ra
+
+ CO(:,ra+1-i)=Ac^(i-1)*Bc;
+
+ end
+
+ //------------------------------------------------------------------
+
+ chr_eq=poly(pl,''s'');
+
+ des_chr_coeff=coeff(chr_eq);
+
+
+ des_chr_coeff=des_chr_coeff(1:ra);
+
+ alpha_c=Ac^ra;
+
+
+ for k=1:ra
+
+ alpha_c=alpha_c + des_chr_coeff(k)*Ac^(k-1)
+
+ end
+
+ //------------------------------------------------------------------
+
+ //State feedback gain
+
+ temp=zeros(1,ra);
+
+ temp(1)=1;
+
+ K=temp*inv(CO)*alpha_c;
+
+ K=K/T;
+
+ lambda=spec(a-b*K);
+
+ endfunction
+
+ //------------------------------------------------------------------
+
+ K=acker_dk(F,G,Pc)//Gain computed in book is incorrect.
+
+ disp(K,''K='',"State feedback gain")
+
+ //------------------------------------------------------------------
+
+ //Overall transfer function with reduced order estimator.
+
+ Gred=8.32*(0.096+s)/(0.1 +s)/(8 + 4*s+s^2)
+
+ Gred=syslin(''c'',Gred)
+
+ disp(Gred,''Ys/Rs'',"Overall transfer function with reduced...
+
+ order estimator")
+
+
+ //Compensator
+
+ D=(0.096+s)*(s+1)/(4.08 +s)/(0.0196+s)
+
+ Ds=syslin(''c'',D*8.32)
+
+ disp(Ds,''Ds='',"Compensator transfer function")
+
+ //------------------------------------------------------------------
+
+ //root locus
+
+ evans(D*Gs,100) //Correct root locus
+
+ //------------------------------------------------------------------
+
+ //step response of the system with lag compensation
+
+ t=0:0.1:5;
+
+ ylag=csim(''step'',t,8.32*Gs*D/(1+8.32*Gs*D));
+
+ //------------------------------------------------------------------
+
+ //Discrete-time controller
+
+ sysDc_ss=syslin(''c'',tf2ss(Ds));
+
+ ts=0.1;
+
+ sysDd=dscr(sysDc_ss,ts)
+
+ Gdz=ss2tf(sysDd)
+
+
+ disp(Gdz,"Discrete-time compensator")'
- model: saveAPI.gallery
- pk: 748
+ pk: 127
fields:
save_id: gallery126
name: Ex7_35_model
description: 'Feedback Control of Dynamic Systems (Author: G. F. Franklin, J.
D. Powell and A. Emami-Naeini), 7) State Space Design, 7.35) Integral Control
of a Motor Speed System'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3432
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0" title="Ex7_35_model"><!--Xcos - 1.0 - scilab-5.5.2
@@ -149302,15 +171871,74 @@
x="940.0" y="260.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-2dd55334:14dcbdd0183:-7fd3" parent="-2dd55334:14dcbdd0183:-7fd2"/></XcosDiagram>
media: gallery126.png
+ script_dump: '//Example 7.35
+
+ // Integral Control of a Motor Speed System
+
+
+ //Transfer function model
+
+ num=1;
+
+ s=poly(0,''s'');
+
+ den=(s+3);
+
+ G=syslin(''c'',num/den);
+
+ sys=tf2ss(G)
+
+
+ // State space representation of augmented system
+
+ F=[0 1; 0 -3];
+
+ G=[0 1]'';
+
+ H=[1 0];
+
+ J=0;
+
+
+ //Desired poles for augmented system
+
+ Pc=[-5 -5];
+
+
+ // State feedback gain is
+
+ K=ppol(F,G,Pc)
+
+
+ //Estimator
+
+ Pe=[-10];
+
+ L=ppol(sys.A'',sys.C'',Pe)
+
+
+ // (c) Compare step reference and disturbance response.
+
+
+ // the required values
+
+ // for step reference response switch, set r to 1 and w to 0
+
+ // for step disturbance response switch, set r to 0 and w to 1
+
+
+ r=1
+
+ w=0'
- model: saveAPI.gallery
- pk: 749
+ pk: 128
fields:
save_id: gallery127
name: Ex8_1_model
description: 'Feedback Control of Dynamic Systems (Author: G. F. Franklin, J.
D. Powell and A. Emami-Naeini), 8) Digital Control, 8.1) Digital Controller
using tustin approximation'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3432
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="2.0" title="Ex8_1_model"><!--Xcos - 1.0 - scilab-5.5.2
@@ -150525,15 +173153,53 @@
as="defaultParent" id="-2dd55334:14dcbdd0183:-7fd3" parent="-2dd55334:14dcbdd0183:-7fd2"/><mxPoint
as="origin" y="-3.0"/></XcosDiagram>
media: gallery127.png
+ script_dump: '///Example 8.1
+
+ // Digital Controller using tustin approximation.
+
+
+ //Cntroller
+
+ s=poly(0,''s'');
+
+ numD=s/2+1;
+
+ denD=s/10+1;
+
+ D=10*numD/denD;
+
+ Ds=syslin(''c'',D);
+
+ //sampling freq. = 25 times bandwidth
+
+ Wbw=10;
+
+ Ws=25*Wbw;
+
+ fs=Ws/2/%pi;
+
+ T=1/fs; //sampling time
+
+ a=1;b=-1;
+
+ c=1;d=1;
+
+ //Digital controller
+
+ z=poly(0,''z'');
+
+ Dz=horner(Ds,2/T*(a*z+b)/(c*z+d));
+
+ disp(Dz,''Digital Controller : '')'
- model: saveAPI.gallery
- pk: 750
+ pk: 129
fields:
save_id: gallery128
name: Ex8_2_model
description: 'Feedback Control of Dynamic Systems (Author: G. F. Franklin, J.
D. Powell and A. Emami-Naeini), 8) Digital Control, 8.2) Design of a Space Station
Attitude Digital Controller using Discrete Equivalents'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3432
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="Ex8_2_model"><!--Xcos - 1.0 - scilab-5.5.2
@@ -152228,15 +174894,73 @@
scilabClass=""><mxPoint x="810.0" y="160.0"/><mxPoint x="810.0" y="110.0"/></Array></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="-2dd55334:14dcbdd0183:-7fd3" parent="-2dd55334:14dcbdd0183:-7fd2"/></XcosDiagram>
media: gallery128.png
+ script_dump: '//Example 8.2
+
+ // Design of a Space Station Attitude Digital Controller using
+
+ // Discrete Equivalents
+
+
+ // State space representation of continuous time system
+
+ s=poly(0,''s'');
+
+ num=1;
+
+ den=(s^2);
+
+ Gs=syslin(''c'',num/den);
+
+ Ds=0.81*(s+0.2)/(s+2);
+
+ Ds=syslin(''c'',Ds);
+
+ sysc=Gs*Ds;
+
+
+ //Root locus
+
+ evans(sysc)
+
+ //Contonuous time response of the system
+
+ tc=0:0.1:30;
+
+ syscl=sysc/(1+sysc)
+
+ yc=csim("step",tc,syscl);
+
+ //------------------------------------------------------------------
+
+ // Discretization of the system at
+
+ z=poly(0,''z'')
+
+ // sampling time Ts=1 sec
+
+ Ts=1;
+
+ Dz1=horner(Ds,2/Ts*(z-1)/(z+1))
+
+ disp(Dz1,"Dz1=","Discrete-time controller with Ts=1 sec.")
+
+
+ // sampling time Ts=0.5 sec
+
+ Ts2=0.5;
+
+ Dz2=horner(Ds,2/Ts2*(z-1)/(z+1))
+
+ disp(Dz2,"Dz2=","Discrete-time controller with Ts=0.5 sec.")'
- model: saveAPI.gallery
- pk: 751
+ pk: 130
fields:
save_id: gallery129
name: Ex9_11_model
description: 'Feedback Control of Dynamic Systems (Author: G. F. Franklin, J.
D. Powell and A. Emami-Naeini), 9) Nonlinear Systems, 9.11) Describing Function
for a relay with hysteresis non linearity'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3432
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0" title="Ex9_11_model"><!--Xcos - 1.0 - scilab-5.5.2
@@ -152800,15 +175524,61 @@
x="370.0" y="120.0"/><mxPoint as="targetPoint" x="370.0" y="170.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-2dd55334:14dcbdd0183:-7fd3" parent="-2dd55334:14dcbdd0183:-7fd2"/></XcosDiagram>
media: gallery129.png
+ script_dump: '//Example 9.11
+
+ //Describing Function for a relay with hysteresis nonlinearity.
+
+
+ //Response of the saturation noninearity to sinusoidal input
+
+ ////Describing Functin for relay with hysteresis nonlinearity.
+
+ h=0.1;
+
+ N=1;
+
+ i=1;
+
+
+ for a=0.1:0.025:1
+
+ if a<h then
+
+ Keq(i,1)=0;
+
+ ro(i,1)=0;
+
+ theta(i,1)=0;
+
+ else
+
+ Keq(i,1)=4*N/(%pi*a)*(sqrt(1-(h/a)^2)-%i*h/a);
+
+ [r th]=polar(Keq(i,1));
+
+ ro(i,1)=r; //magnitude
+
+ theta(i,1)=clean(th); //angle in radians
+
+ end
+
+ i=i+1;
+
+ end
+
+
+ a=0.1:0.025:1;
+
+ a=a'';'
- model: saveAPI.gallery
- pk: 752
+ pk: 131
fields:
save_id: gallery130
name: Ex9_13_model
description: 'Feedback Control of Dynamic Systems (Author: G. F. Franklin, J.
D. Powell and A. Emami-Naeini), 9) Nonlinear Systems, 9.13) Determination of
stability with a hysteresis nonlinearity'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3432
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="50.0" title="Ex9_13_model"><!--Xcos - 1.0 - scilab-5.5.2
@@ -153388,15 +176158,60 @@
x="590.0" y="170.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-2dd55334:14dcbdd0183:-7fd3" parent="-2dd55334:14dcbdd0183:-7fd2"/></XcosDiagram>
media: gallery130.png
+ script_dump: '//Example 9.13
+
+ //Determination of stability with a hysteresis nonlinearity.
+
+
+ //System Model
+
+ s=poly(0,''s'');
+
+ num=1;
+
+ den=(s^2+s);
+
+ Gs=syslin(''c'',num/den);
+
+
+ // Nyquist Plot of Describing Function for hysteresis nonlinearity
+
+ N=1;
+
+ h=0.1;
+
+ i=1;
+
+
+ for omegat=0:0.05:%pi-0.1;
+
+ a=sin(omegat);
+
+ DF_nyq(i,1)=-%pi/4/N*(sqrt(a^2-h^2) + h * %i);
+
+ i=i+1;
+
+ end
+
+
+ //Response of the system
+
+ K=2;
+
+
+ // the required value
+
+
+ r=1'
- model: saveAPI.gallery
- pk: 753
+ pk: 132
fields:
save_id: gallery131
name: Ex9_5_model
description: 'Feedback Control of Dynamic Systems (Author: G. F. Franklin, J.
D. Powell and A. Emami-Naeini), 9) Nonlinear Systems, 9.5) Changing Overshoot
and Saturation nonlinearity'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3432
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="Ex9_5_model"><!--Xcos - 1.0 - scilab-5.5.2
@@ -154061,15 +176876,43 @@
as="geometry" height="40.0" width="40.0" x="510.0" y="140.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-2dd55334:14dcbdd0183:-7fd3" parent="-2dd55334:14dcbdd0183:-7fd2"/></XcosDiagram>
media: gallery131.png
+ script_dump: '//Example 9.5
+
+ //Changing Overshoot and Saturation nonlinearity.
+
+
+ //System transfer function and its root locus
+
+
+ s=poly(0,''s'');
+
+ num=(s+1)
+
+ den=(s^2);
+
+ Gs=syslin(''c'',num/den)
+
+
+ //Root locus
+
+ evans(Gs,5)
+
+ // Step response
+
+ K=1;
+
+ i=[2 4 6 8 10 12];
+
+ r=2'
- model: saveAPI.gallery
- pk: 754
+ pk: 133
fields:
save_id: gallery132
name: Ex9_6_model
description: 'Feedback Control of Dynamic Systems (Author: G. F. Franklin, J.
D. Powell and A. Emami-Naeini), 9) Nonlinear Systems, 9.6) Stability of conditionally
stable system using root locus'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3432
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="20.0" title="Ex9_6_model"><!--Xcos - 1.0 - scilab-5.5.2
@@ -154674,15 +177517,41 @@
x="530.0" y="180.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-2dd55334:14dcbdd0183:-7fd3" parent="-2dd55334:14dcbdd0183:-7fd2"/></XcosDiagram>
media: gallery132.png
+ script_dump: '//Example 9.6
+
+ //Stability of conditionally stable system using root locus.
+
+ //System transfer function and its root locus
+
+
+ s=poly(0,''s'');
+
+ num=(s+1)^2
+
+ den=(s^3);
+
+ Gs=syslin(''c'',num/den)
+
+ //Root locus
+
+ evans(Gs,7)
+
+ //Response of the system
+
+ K=2;
+
+ i=[1 2 3 3.475];
+
+ r=1'
- model: saveAPI.gallery
- pk: 755
+ pk: 134
fields:
save_id: gallery133
name: Ex9_7_model_notch
description: 'Feedback Control of Dynamic Systems (Author: G. F. Franklin, J.
D. Powell and A. Emami-Naeini), 9) Nonlinear Systems, 9.7) Analysis and design
of the system with limit cycle using the root locus'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3432
data_dump: '<?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="50.0" title="Ex9_7_model_notch"><!--Xcos - 1.0 - scilab-5.5.2
@@ -155354,15 +178223,60 @@
x="740.0" y="170.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-2dd55334:14dcbdd0183:-7fd3" parent="-2dd55334:14dcbdd0183:-7fd2"/></XcosDiagram>'
media: gallery133.png
+ script_dump: '//Example 9.7
+
+ //Analysis and design of the system with limit cycle using the root locus.
+
+ //System transfer function and its root locus
+
+
+ s=poly(0,''s'');
+
+ num=0.1;
+
+ den=(s^2+0.2*s+1)*(s);
+
+ Gs=syslin(''c'',num/den);
+
+
+ //Root locus
+
+ evans(Gs,40)
+
+ //Response of the system
+
+ K=0.5;
+
+ i=[1 4 8];
+
+ r=1
+
+
+ //System with notch compensation
+
+ D=123*(s^2+0.18*s+0.81)/(s+10)^2;
+
+
+ //Root locus
+
+ evans(Gs*D,40)
+
+ //Response of the system witth notch filter
+
+ K=0.5;
+
+ i=[2 4];
+
+ r=2'
- model: saveAPI.gallery
- pk: 756
+ pk: 135
fields:
save_id: gallery134
name: Ex9_7_model
description: 'Feedback Control of Dynamic Systems (Author: G. F. Franklin, J.
D. Powell and A. Emami-Naeini), 9) Nonlinear Systems, 9.7) Analysis and design
of the system with limit cycle using the root locus'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3432
data_dump: '<?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="150.0" title="Ex9_7_model"><!--Xcos - 1.0 - scilab-5.5.2
@@ -155986,15 +178900,60 @@
x="750.0" y="170.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-2dd55334:14dcbdd0183:-7fd3" parent="-2dd55334:14dcbdd0183:-7fd2"/></XcosDiagram>'
media: gallery134.png
+ script_dump: '//Example 9.7
+
+ //Analysis and design of the system with limit cycle using the root locus.
+
+ //System transfer function and its root locus
+
+
+ s=poly(0,''s'');
+
+ num=0.1;
+
+ den=(s^2+0.2*s+1)*(s);
+
+ Gs=syslin(''c'',num/den);
+
+
+ //Root locus
+
+ evans(Gs,40)
+
+ //Response of the system
+
+ K=0.5;
+
+ i=[1 4 8];
+
+ r=1
+
+
+ //System with notch compensation
+
+ D=123*(s^2+0.18*s+0.81)/(s+10)^2;
+
+
+ //Root locus
+
+ evans(Gs*D,40)
+
+ //Response of the system witth notch filter
+
+ K=0.5;
+
+ i=[2 4];
+
+ r=2'
- model: saveAPI.gallery
- pk: 757
+ pk: 136
fields:
save_id: gallery135
name: Ex9_8_model
description: 'Feedback Control of Dynamic Systems (Author: G. F. Franklin, J.
D. Powell and A. Emami-Naeini), 9) Nonlinear Systems, 9.8) Antiwindup compensation
for a PI controller'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3432
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="10.0" title="Ex9_8_model"><!--Xcos - 1.0 - scilab-5.5.2
@@ -157050,15 +180009,38 @@
x="890.0" y="100.0"/><Array as="points" scilabClass=""><mxPoint x="810.0" y="100.0"/></Array></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="-2dd55334:14dcbdd0183:-7fd3" parent="-2dd55334:14dcbdd0183:-7fd2"/></XcosDiagram>
media: gallery135.png
+ script_dump: '//Example 9.8
+
+ //Antiwindup compensation for a PI controller.
+
+
+ //System Model
+
+
+ //Response of the system
+
+ kp=2;
+
+ ki=4;
+
+
+ //Without antiwindup
+
+ ka=0;
+
+
+ //With antiwindup
+
+ ka=10;'
- model: saveAPI.gallery
- pk: 758
+ pk: 137
fields:
save_id: gallery136
name: Ex9_9_model
description: 'Feedback Control of Dynamic Systems (Author: G. F. Franklin, J.
D. Powell and A. Emami-Naeini), 9) Nonlinear Systems, 9.9) Describing Function
for a saturation nonlinearity'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3432
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="5.0" title="Ex9_9_model"><!--Xcos - 1.0 - scilab-5.5.2
@@ -157624,14 +180606,52 @@
as="geometry" height="40.0" width="40.0" x="360.0" y="140.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="-2dd55334:14dcbdd0183:-7fd3" parent="-2dd55334:14dcbdd0183:-7fd2"/></XcosDiagram>
media: gallery136.png
+ script_dump: '//Example 9.9
+
+ //Describing Function for a saturation nonlinearity.
+
+
+ //Response of the saturation nonlinearity to sinusoidal input
+
+ //Describing Functin for saturation nonlinearity.
+
+ k=1;
+
+ N=1;
+
+ i=1;
+
+ Keq=[];
+
+
+ for a=0:0.2:10
+
+ if k*a/N > 1 then
+
+ Keq(i,1)=2/%pi*(k*asin(N/a/k)+N/a*sqrt(1-(N/k/a)^2))
+
+ else
+
+ Keq(i,1)=k
+
+ end
+
+ i=i+1;
+
+ end
+
+
+ a=0:0.2:10;
+
+ a=a'';'
- model: saveAPI.gallery
- pk: 759
+ pk: 138
fields:
save_id: gallery137
name: Ex3_1
description: 'Control Systems (Author: A Nagoor Kani), 3) TIME RESPONSE ANALYSIS,
3.1) RESPONSE OF THE SYSTEM'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3885
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="Ex3_1"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -158259,14 +181279,44 @@
x="180.0" y="200.0"/></Array></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="0:2:0" parent="0:1:0"/></XcosDiagram>
media: gallery137.png
+ script_dump: '//control systems by Nagoor Kani A
+
+ //Edition 3
+
+ //Year of publication 2015
+
+ //Scilab version 6.0.0
+
+ //operating systems windows 10
+
+ // Example 3.1
+
+
+ s=%s
+
+ p=poly([4],''s'',''coeff'')
+
+ q=poly([0 5 1],''s'',''coeff'')
+
+ g=p./q
+
+ disp(g,''The given transfer function is'')
+
+ c=g/(1+g)
+
+ disp(c,''The closed loop transfer function is'')
+
+ u=c/s
+
+ disp(u,''The input is unit step signal'')'
- model: saveAPI.gallery
- pk: 760
+ pk: 139
fields:
save_id: gallery138
name: Ex3_2
description: 'Control Systems (Author: A Nagoor Kani), 3) TIME RESPONSE ANALYSIS,
3.2) RESPONSE OF THE SYSTEM'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3885
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="Ex3_2"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -158852,14 +181902,46 @@
x="340.0" y="70.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="0:2:0" parent="0:1:0"/></XcosDiagram>
media: gallery138.png
+ script_dump: '//control systems by Nagoor Kani A
+
+ //Edition 3
+
+ //Year of publication 2015
+
+ //Scilab version 6.0.0
+
+ //operating systems windows 10
+
+ // Example 3.2
+
+
+ s=%s
+
+ p=poly([100],''s'',''coeff'')
+
+ q=poly([0 2 1],''s'',''coeff'')
+
+ h=poly([1 0.1 0 ],''s'',''coeff'')
+
+ g=p./q
+
+ disp(g,''the given transfer function is'')
+
+ c=g/(1+(g*h))
+
+ disp(c,''the closed loop transfer function is'')
+
+ u=c/s
+
+ disp(u,''the in put is unit step signal'')'
- model: saveAPI.gallery
- pk: 761
+ pk: 140
fields:
save_id: gallery139
name: Ex3_6
description: 'Control Systems (Author: A Nagoor Kani), 3) TIME RESPONSE ANALYSIS,
3.6) RESPONSE OF THE SYSTEM'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3885
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="Ex3_6"><!--Xcos - 1.0 - scilab-5.5.2 - 20181120--><mxGraphModel
@@ -159445,14 +182527,76 @@
x="360.0" y="260.0"/></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="0:2:0" parent="0:1:0"/></XcosDiagram>
media: gallery139.png
+ script_dump: '//control systems by Nagoor Kani A
+
+ //Edition 3
+
+ //Year of publication 2015
+
+ //Scilab version 6.0.0
+
+ //operating systems windows 10
+
+ // Example 3.6
+
+
+ s=poly(0,''s'')
+
+ // the input is unit step signal
+
+ h=syslin(''c'',16/(s^2+4*s+16))//the value of k is 0.2
+
+ zeta=0.5//given damping ratio
+
+ disp(h,''the closed loop transfer function'')
+
+ //standard form od second order system is w^2/s^2+2*zeta*w*s+w^2
+
+ //compaing h with the standard form
+
+ w=4//natural frequency of oscillation
+
+ disp(w,''natural frequency of oscillation in rad/sec'')
+
+ k=(2*zeta*w-(0.8))/16
+
+ disp(k,''the value of k is'')
+
+ mp=exp((-zeta*%pi)/sqrt(1-(zeta)^2))*100//percentage peak overshoot
+
+ disp(mp,''percentage peak overshoot in percentage'')
+
+ tp=%pi/(w*sqrt(1-(zeta)^2))
+
+ disp(tp,''peak time in seconds'')
+
+ //constructing a right angle triangle with zeta and sqrt(1-zeta^2)
+
+ theta=atan(0.866/0.5)//(1-zeta^2)/zeta
+
+ disp(theta,''the value of theta is'')
+
+ tr=(%pi- theta)/(w*sqrt(1-(zeta)^2))
+
+ disp(tr,''the rise time in seconds'')
+
+ t=1/(zeta*w)//time constant
+
+ ts1=3*t//settling time for 5% error
+
+ disp(ts1,''settling time for 5% error in seconds'')
+
+ ts2=4*t//settling time for 2% error
+
+ disp(ts2,''settling time for 2% error in seconds'')'
- model: saveAPI.gallery
- pk: 762
+ pk: 141
fields:
save_id: gallery140
name: Ex3_7
description: 'Control Systems (Author: A Nagoor Kani), 3) TIME RESPONSE ANALYSIS,
3.7) RESPONSE OF THE SYSTEM'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3885
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="Ex3_7"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -160038,14 +183182,64 @@
x="480.0" y="100.0"/><mxPoint as="targetPoint" x="480.0" y="170.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="0:2:0" parent="0:1:0"/></XcosDiagram>
media: gallery140.png
+ script_dump: '//control systems by Nagoor Kani A
+
+ //Edition 3
+
+ //Year of publication 2015
+
+ //Scilab version 6.0.0
+
+ //operating systems windows 10
+
+ // Example 3.7
+
+
+ s=%s
+
+ p=poly([1 0.4 0 ],''s'',''coeff'')
+
+ q=poly([0 0.6 1],''s'',''coeff'')
+
+ g=p./q
+
+ disp(g,''the given transfer function is'')
+
+ c=g/(1+g)
+
+ disp(c,''the closed loop transfer function is'')
+
+ u=c/s
+
+ disp(u,''the in put is unit step signal'')
+
+ //standard form od second order system is w^2/s^2+2*zeta*w*s+w^2
+
+ //compaing h with the standard form
+
+ w=1//natural frequency of oscillation
+
+ disp(w,''natural frequency of oscillation in rad/sec'')
+
+ zeta=1/(2*w)
+
+ disp(zeta,''the damping ratio is'')
+
+ mp=exp((-zeta*%pi)/sqrt(1-(zeta)^2))*100//percentage peak overshoot
+
+ disp(mp,''percentage peak overshoot in percentage'')
+
+ tp=%pi/(w*sqrt(1-(zeta)^2))
+
+ disp(tp,''peak time in seconds'')'
- model: saveAPI.gallery
- pk: 763
+ pk: 142
fields:
save_id: gallery141
name: Ex7_10
description: 'Control Systems (Author: A Nagoor Kani), 7) STATE SPACE ANALYSIS,
7.10) STATE MODEL'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3885
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="Ex7_10"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -160637,14 +183831,36 @@
x="360.0" y="110.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="0:2:0" parent="0:1:0"/></XcosDiagram>
media: gallery141.png
+ script_dump: '//control systems by Nagoor Kani A
+
+ //Edition 3
+
+ //Year of publication 2015
+
+ //Scilab version 6.0.0
+
+ //operating systems windows 10
+
+ // Example 7.10
+
+
+ s=%s
+
+ p=poly([10],''s'',''coeff'')
+
+ q=poly([1 2 4 1],''s'',''coeff'')
+
+ sm=cont_frm(p,q)
+
+ disp(sm,''the state model in matrix form is'')'
- model: saveAPI.gallery
- pk: 764
+ pk: 143
fields:
save_id: gallery142
name: Ex7_11
description: 'Control Systems (Author: A Nagoor Kani), 7) STATE SPACE ANALYSIS,
7.11) STATE MODEL'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3885
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="Ex7_11"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -161236,14 +184452,36 @@
x="270.0" y="210.0"/><mxPoint as="targetPoint" x="330.0" y="220.0"/></mxGeometry></ExplicitLink></root></mxGraphModel><mxCell
as="defaultParent" id="0:2:0" parent="0:1:0"/></XcosDiagram>
media: gallery142.png
+ script_dump: '//control systems by Nagoor Kani A
+
+ //Edition 3
+
+ //Year of publication 2015
+
+ //Scilab version 6.0.0
+
+ //operating systems windows 10
+
+ // Example 7.11
+
+
+ s=%s
+
+ p=poly([40 10],''s'',''coeff'')
+
+ q=poly([0 3 4 1],''s'',''coeff'')
+
+ sm=cont_frm(p,q)
+
+ disp(sm,''the state model in matrix form is'')'
- model: saveAPI.gallery
- pk: 765
+ pk: 144
fields:
save_id: gallery143
name: Ex7_12
description: 'Control Systems (Author: A Nagoor Kani), 7) STATE SPACE ANALYSIS,
7.12) STATE MODEL'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 3885
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="30.0" title="Ex7_12"><!--Xcos - 1.0 - scilab-5.5.2 - 20160406
@@ -161836,14 +185074,40 @@
as="sourcePoint" x="360.0" y="120.0"/><mxPoint as="targetPoint" x="360.0" y="140.0"/></mxGeometry></CommandControlLink></root></mxGraphModel><mxCell
as="defaultParent" id="0:2:0" parent="0:1:0"/></XcosDiagram>
media: gallery143.png
+ script_dump: '//control systems by Nagoor Kani A
+
+ //Edition 3
+
+ //Year of publication 2015
+
+ //Scilab version 6.0.0
+
+ //operating systems windows 10
+
+ // Example 7.12
+
+
+ s=%s
+
+ h=syslin(''c'',(2*(s+5))/((s+2)*(s+3)*(s+4)))
+
+ disp(h,''thr transfer function is'')
+
+ ss=tf2ss(h)
+
+ disp(ss,''the state space model is'')
+
+ [Ac,Bc,U,ind]=canon(ss(2),ss(3))
+
+ disp(Ac,Bc,U,ind)'
- model: saveAPI.gallery
- pk: 766
+ pk: 145
fields:
save_id: gallery144
name: example_11_1
description: 'Modern Power System Analysis (Author: D. P. Kothari And I. J. Nagrath),
11) Unsymmetrical Fault Analysis, 11.1) LG and 3Phase faults Comparision'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 83
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.25" title="example_11_1"><!--Xcos - 1.0 - scilab-5.5.2
@@ -162975,15 +186239,49 @@
as="geometry" height="8.0" width="8.0" x="16.0" y="-8.0"/></ImplicitInputPort></root></mxGraphModel><mxCell
as="defaultParent" id="67e02cde:13157ae1f65:-8000" parent="67e02cde:13157ae1f65:-7fff"/></XcosDiagram>
media: gallery144.png
+ script_dump: '//Chapter 11
+
+ //Example 11.1
+
+ //page 406
+
+ //To draw sequence networks of generator and to compare LG fault current will
+ be greater than three-phase fault current when neutral is solidly grounded
+
+
+ disp("Sequence networks of synchronous generator grounded through neutral impedance
+ has been drawn using XCOS ");
+
+
+ disp("Since the derivation can not be done here, let us do this problem by taking
+ a suitable values for the sequence reactances of the generator");
+
+
+ disp("X1=j0.18, X2=j0.15, X0=j0.10 pu and Ea=1");
+
+
+ disp("From the figs 11.13 and 11.14 in the textbook,we can find Ilg and I3L");
+
+
+ Ea=1;X1=0.18*%i;X2=0.15*%i;X0=0.10*%i;
+
+
+ IaLG=3*Ea/(2*X1+X0)
+
+ Ia3L=3*Ea/(3*X1)
+
+
+ disp("Same values of sequence impedance have been used in XCOS simulation also
+ to varify the result");'
- model: saveAPI.gallery
- pk: 767
+ pk: 146
fields:
save_id: gallery145
name: example_11_2
description: 'Modern Power System Analysis (Author: D. P. Kothari And I. J. Nagrath),
11) Unsymmetrical Fault Analysis, 11.2) Grounding Resistor voltage and Fault
Current'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 83
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.25" title="example_11_2"><!--Xcos - 1.0 - scilab-5.5.2
@@ -164135,15 +187433,53 @@
as="geometry" height="8.0" width="8.0" x="16.0" y="-8.0"/></ImplicitInputPort></root></mxGraphModel><mxCell
as="defaultParent" id="67e02cde:13157ae1f65:-7afa" parent="67e02cde:13157ae1f65:-7af9"/></XcosDiagram>
media: gallery145.png
+ script_dump: '//Chapter 11
+
+ //Example 11.2
+
+ //page 408
+
+ //To find fault current and voltage across the grounding resistor
+
+
+ X1eq=(%i*0.18)/2;
+
+ X2eq=(%i*0.15)/2;
+
+ Z0eq=(%i*0.10)+3*(2*20/(11^2));
+
+
+ Ea=1;
+
+
+ //calculation of fault current
+
+ printf(''\nFault current is given by '');
+
+ If=(3*Ea)/(X1eq+X2eq+Z0eq)
+
+
+ //current in grounding resistor
+
+ Ifg=abs(If)*(20/(11*sqrt(3)));
+
+ printf(''\n\nCurrent through grounding resistor Ifg=%0.2fkA'',Ifg);
+
+
+ //voltage across grounding resistor
+
+ Vgr=abs(If*(2*20/(11^2))*(11/sqrt(3)));
+
+ printf(''\n\nVoltage across grounding resistor Vgr=%0.2fkV\n\n'',Vgr);'
- model: saveAPI.gallery
- pk: 768
+ pk: 147
fields:
save_id: gallery146
name: example_11_3
description: 'Modern Power System Analysis (Author: D. P. Kothari And I. J. Nagrath),
11) Unsymmetrical Fault Analysis, 11.3) Fault and subtransient currents of the
system'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 83
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.25" title="example_11_3"><!--Xcos - 1.0 - scilab-5.5.2
@@ -165468,14 +188804,153 @@
as="geometry" height="40.0" width="40.0" x="790.0" y="250.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="2af926ac:131590fb290:-7ef4" parent="2af926ac:131590fb290:-7ef3"/></XcosDiagram>
media: gallery146.png
+ script_dump: '//Chapter 11
+
+ //Example 11.3
+
+ //page 409
+
+ //To find fault current and subtransient current in all parts of the system
+
+
+ a=-0.5+(sqrt(3)/2)*%i;
+
+
+ //neglecting prefault currents
+
+ Vf0=10/11;
+
+ Eg=Vf0; Em1=Vf0 ;Em2=Vf0;
+
+
+ //positive sequence network when it is replaced by its thevenin''s equvivalent
+ as shown in fig11.18
+
+ printf(''\nsequence impedances are given by \n'');
+
+ Z1=(%i*0.525*%i*0.23)/(%i*0.755);
+
+ Z2=Z1;
+
+ Z0=%i*1.712;
+
+ printf(''Z1=j%0.4f \nZ2=j%0.4f \nZ0=j%0.4f'',abs(imag(Z1)),abs(imag(Z2)),abs(imag(Z0)));
+
+ //to find sequence current
+
+ Ia1=Vf0/(Z1+Z2+Z0);
+
+ Ia2=Ia1;
+
+ Ia0=Ia1;
+
+
+ //to find fault current
+
+ If=3*Ia0;
+
+ printf(''\n\nFault Current= -j%0.4f'',abs(imag(If)));
+
+
+
+ //component current flowing from generator and motor
+
+ printf(''\n\nComponents currents flowing from Generator and motor are \n'')
+
+ Ig1=Ia1*(0.23/0.755) ;
+
+ Ig2=Ig1;
+
+ Ig0=0;
+
+ printf(''Ig1= -j%0.4f \nIg2= -j%0.4f \nIg0=%d'',abs(Ig1),abs(Ig2),abs(Ig0));
+
+ printf(''\n'');
+
+ Im1=Ia1*(0.525/0.755);
+
+ Im2=Im1;
+
+ Im0=Ia0;
+
+ printf(''\nIm1= -j%0.4f \nIm2= -j%0.4f \nIm0= -j%0.4f'',abs(Im1),abs(Im2),abs(Im0));
+
+
+ //fault currents from the generator and motor towards g are
+
+ printf(''\n\nFault current from the generator towards g are '');
+
+ Ig=[1 1 1;a^2 a 1;a a^2 1]*[Ig1;Ig2;Ig0];
+
+ disp(Ig);
+
+ printf(''and to g from motors are'');
+
+ Im=[1 1 1;a^2 a 1;a a^2 1]*[Im1;Im2;Im0];
+
+ disp(Im);
+
+
+ printf(''\nPositive sequence current =%0.3f pu'',(-%i*Ig1));
+
+ printf(''\nNegative sequence current =%0.3f pu'',(%i*Ig2));
+
+ printf(''\nZero sequence current=%d\n'',Ig0);
+
+
+ //under loaded condition,PU motor currents are
+
+ Im1o=(15/(25*0.909*0.8))*(0.800103636+%i*0.5998617938);
+
+ Im2o=(7.5/(25*0.909*0.8))*(0.800103636+%i*0.5998617938);
+
+ printf(''\nThe per unit motor currents are:\n'');
+
+ printf(''Motor1:%0.2f +j%0.3f pu'',real(Im1o),imag(Im1o));
+
+ printf(''\nMotor2:%0.2f +j%0.3f pu'',real(Im2o),imag(Im2o));
+
+
+ //the voltages behind subtransient reactances are calculated below
+
+ printf(''\n\nVoltage behind subtransient reactances:\n'');
+
+ printf(''Motor1:'');
+
+ Em1=Em1-(%i*0.345*Im1o);
+
+ printf(''Em1= %0.4f-j%0.4f'',real(Em1),abs(imag(Em1)));
+
+
+ printf(''\nMotor2:'');
+
+ Em2=Em2-(%i*0.69*Im2o);
+
+ printf(''Em2= %0.4f-j%0.4f'',real(Em2),abs(imag(Em2)));
+
+
+ printf(''\nGenerator:'');
+
+ Eg=Eg+(%i*0.525*(Im2o+Im1o));
+
+ printf(''Eg= %0.4fj+%0.4f'',real(Eg),abs(imag(Eg)));
+
+
+ //actual value of positive sequence current from generator and motor
+
+ printf(''\n\nThe actual value of positive sequence current from the generator
+ towards fault is = %0.2f+j%0.3f'',real(Im1o+Im2o+Ig1),imag(Im1o+Im2o+Ig1));
+
+ printf(''\nThe actual value of positive sequence current from the motors towards
+ fault is = %0.2f-j%0.3f'',real(-Im1o-Im2o+Im1),abs(imag(-Im1o-Im2o+Im1)));'
- model: saveAPI.gallery
- pk: 769
+ pk: 148
fields:
save_id: gallery147
name: example_11_4
description: 'Modern Power System Analysis (Author: D. P. Kothari And I. J. Nagrath),
11) Unsymmetrical Fault Analysis, 11.4) LL Fault Current'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 83
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.25" title="example_11_4"><!--Xcos - 1.0 - scilab-5.5.2
@@ -166349,14 +189824,63 @@
as="geometry" height="8.0" width="8.0" x="16.0" y="60.0"/></ImplicitOutputPort></root></mxGraphModel><mxCell
as="defaultParent" id="-1f09110a:1315ad634dc:-8000" parent="-1f09110a:1315ad634dc:-7fff"/></XcosDiagram>
media: gallery147.png
+ script_dump: '//Chapter 11
+
+ //Example 11.4
+
+ //page 412
+
+ //To find L-L fault current and voltage of healthy phase
+
+ X1eq=0.09*%i;
+
+ X2eq=0.075*%i;
+
+ Z0=0.99+(%i*0.1);
+
+ Ea=1;Ia0=0;
+
+
+ //to calculate Ia1
+
+ Ia1=Ea/(X1eq+X2eq);
+
+
+ //to calculate fault current
+
+ If=(-%i*sqrt(3))*(-%i*6.06);
+
+ Va1=Ea-(Ia1*X1eq);
+
+ Va0=(-Ia0*Z0);
+
+ Va2=Va1;
+
+
+ //voltage in healthy phase
+
+ Va=Va1+Va2+Va0;
+
+
+ //displaying the result
+
+ printf(''\nIa1=-j%0.2f'',abs(Ia1));
+
+ printf(''\nIf=%0.3f'',If);
+
+ printf(''\nVa1=Va2=%0.3f'',Va1);
+
+ printf(''\nVa0=%d'',Va0);
+
+ printf(''\nVa=Va1+Va2+Va0=%0.2f\n\n'',Va);'
- model: saveAPI.gallery
- pk: 770
+ pk: 149
fields:
save_id: gallery148
name: example_11_5
description: 'Modern Power System Analysis (Author: D. P. Kothari And I. J. Nagrath),
11) Unsymmetrical Fault Analysis, 11.5) Double line to ground Fault'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 83
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.25" title="example_11_5"><!--Xcos - 1.0 - scilab-5.5.2
@@ -167388,14 +190912,75 @@
as="geometry" height="8.0" width="8.0" x="16.0" y="-8.0"/></ImplicitInputPort></root></mxGraphModel><mxCell
as="defaultParent" id="-1f09110a:1315ad634dc:-8000" parent="-1f09110a:1315ad634dc:-7fff"/></XcosDiagram>
media: gallery148.png
+ script_dump: '//Chapter 11
+
+ //Example 11.5
+
+ //page 413
+
+ //To find Double line to ground fault current and voltage of healthy phase
+
+
+ Z1eq=0.09*%i;
+
+ Z2eq=0.075*%i;
+
+ Z0=(%i*0.1);
+
+ Ea=1;
+
+ a=(-0.5+%i*sqrt(3)/2);
+
+
+ //to find the sequence components of healthy phase
+
+ Ia1=Ea/(Z1eq+(Z2eq*Z0/(Z2eq+Z0)));
+
+ Va1=Ea-(Ia1*Z1eq);
+
+ Va2=Va1;
+
+ Va0=Va1;
+
+
+ Ia2=-(Va2/Z2eq);
+
+ Ia0=-(Va0/Z0);
+
+
+ I=[1 1 1;a^2 a 1;a a^2 1]*[Ia1; Ia2; Ia0];
+
+
+ //voltage of the healthy phase
+
+ Va=3*Va1;
+
+
+ //displaying the results
+
+ printf(''Ia1=-j%0.3f\n'',abs(Ia1));
+
+ printf('' Ia2=j%0.3f\n'',abs(Ia2));
+
+ printf('' Ia0=j%0.3f\n\n'',abs(Ia0));
+
+
+ printf('' Ia=%0.3f + j%0.3f\n'',real(I(1,1)),imag(I(1,1)));
+
+ printf('' Ib=%0.3f + j%0.3f\n'',real(I(2,1)),imag(I(2,1)));
+
+ printf('' Ic=%0.3f + j%0.3f\n\n'',real(I(3,1)),imag(I(3,1)));
+
+
+ printf('' Voltage of the healthy phase Va=3Va1=%0.3f'',Va);'
- model: saveAPI.gallery
- pk: 771
+ pk: 150
fields:
save_id: gallery149
name: example_9_1_3phase_plot
description: 'Modern Power System Analysis (Author: D. P. Kothari And I. J. Nagrath),
9) Symmetrical Fault Analysis, 9.1) Fault Current Calculation'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 83
data_dump: '<?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.2" title="example_9_1_3phase_plot"><!--Xcos - 1.0 -
@@ -170445,14 +194030,95 @@
x="1590.0" y="550.0"/></TextBlock></root></mxGraphModel><mxCell as="defaultParent"
id="-62268d13:130f6b46d8a:-7eeb" parent="-62268d13:130f6b46d8a:-7eea"/></XcosDiagram>'
media: gallery149.png
+ script_dump: '//Chapter 9
+
+ //Example 9.1
+
+ //page 335
+
+ //To calculate fault current
+
+ //selecting base KVA and MVA
+
+ mvab=100;
+
+ Gmva=10;
+
+ T1mva=10; T2mva=5;
+
+ Gkvb=11; //generator kV base
+
+ OHLkvb=33; //overhead line kV base
+
+ Ckvb=6.6;// cable kB base
+
+ xg1=%i*0.15; xg2=%i*0.125; xt1=%i*0.10; xt2=%i*0.08;
+
+ xOHL=0.27+%i*0.36 ; xcab= 0.135+%i*0.08;
+
+
+ //clculating PU impedances
+
+
+ xg1=(xg1*mvab)/Gmva;
+
+ xg2=(xg2*mvab)/Gmva;
+
+ xt1=(xt1*mvab)/T1mva;
+
+ xt2=(xt2*mvab)/T2mva;
+
+ xOHL=(30*xOHL*mvab)/(OHLkvb^2);
+
+ xcab=(3*xcab*mvab)/(Ckvb^2);
+
+ //displaying results
+
+ printf(''\n Reactance of G1= j%0.1f pu \n'',abs(imag(xg1)));
+
+ printf('' Reactance of G2= j%0.1f pu\n'',abs(imag(xg2)));
+
+ printf('' Reactance of T1= j%0.1f pu\n'',abs(imag(xt1)));
+
+ printf('' Reactance of T2= j%0.1f pu\n'',abs(imag(xt2)));
+
+ printf('' Overhead line impedance=(%0.3f + j%0.3f) pu\n'',real(xOHL),abs(imag(xOHL)));
+
+ printf('' Cable impedance= (%0.3f + j%0.3f) pu\n'',real(xcab),abs(imag(xcab)));
+
+
+ // Impedance diagram is as shown in the figure9.7 in the textbook
+
+ // A XCOS simulation for this proble is done to explain the subtransient,transient
+ and steady state periods of a symmetrical short circuit
+
+ xtotal=((xg1*xg2)/(xg1+xg2)+xt1+xt2+xOHL+xcab);
+
+ Isc_pu=(1/xtotal);
+
+ Ibase=(mvab/(sqrt(3)*Ckvb))*1000;
+
+ Isc=Isc_pu*Ibase;
+
+ x_F_to_bus=(xt1+xt2+xOHL+xcab);
+
+ v_11b=x_F_to_bus*Isc_pu*11;
+
+ //displaying results
+
+ printf(''\nTotal impedance= %0.1f < %0.2f deg pu \n'',abs(xtotal),atand(imag(xtotal)/real(xtotal)));
+
+ printf(''Short circuit current= %d A\n'',abs(Isc));
+
+ printf(''Voltage at 11kV bus=%0.2f kV\n'',abs(v_11b));'
- model: saveAPI.gallery
- pk: 772
+ pk: 151
fields:
save_id: gallery150
name: example_9_2
description: 'Modern Power System Analysis (Author: D. P. Kothari And I. J. Nagrath),
9) Symmetrical Fault Analysis, 9.2) Subtransient and Momentary current Calculation'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 83
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.5" title="example_9_2"><!--Xcos - 1.0 - scilab-5.5.2
@@ -171708,14 +195374,95 @@
as="defaultParent" id="63eb11b3:131137cfac5:-8000" parent="63eb11b3:131137cfac5:-7fff"/><mxPoint
as="origin" y="-20.0"/></XcosDiagram>
media: gallery150.png
+ script_dump: '//Chapter 9
+
+ //Example 9.2
+
+ //page 337
+
+ //To calculate subtransient and momentary current
+
+ mvab=25;
+
+ Gmva=25;
+
+ T1mva=25; T2mva=25;
+
+ Gkvb=11; //generator kV base
+
+ OHLkvb=66; //overhead line kV base
+
+ Mkvb=6.6; //motor kV base
+
+ Mmva=5; //motor mva
+
+
+ XdG=%i*0.2; //Generator''s subtransient reactance
+
+ XdM=%i*0.25; //Motor''s subtransient reactance
+
+ XdM2=%i*0.3; //Motor''s transient reactance
+
+ Xt1=%i*0.1; // step up transformer''s reactance
+
+ Xt2=%i*0.1;//step down transformer''s reactance
+
+ Xtl=%i*0.15 ;//trnasmission line''s reactance
+
+
+ //per unit calculation
+
+ XdM=(XdM*mvab)/Mmva ;//perunit impedance of each motor
+
+ printf(''\nSubtransient reactance of each motor = j%0.2f pu\n'',abs(XdM));
+
+
+ //(a)subtransient current in the fault
+
+ Isc=(3*(1/XdM))+(1/(XdG+Xt1+Xt2+Xtl));
+
+ Ibase=(mvab*1000)/(sqrt(3)*Mkvb);
+
+ Isc=Isc*Ibase;
+
+ printf(''\nSubtransient current in the fault =%0.1fA\n'',abs(Isc));
+
+
+ //(b)subtransient current in the breaker B
+
+ IscB=(2*(1/XdM))+(1/(XdG+Xt1+Xt2+Xtl));
+
+ IscB=IscB*Ibase;
+
+ printf(''\nSubtransient current in breaker B=%0.1fA\n'',abs(IscB));
+
+
+ //(c) to find the momentary current through breaker B
+
+ ImomB=1.6*IscB;
+
+ printf(''\nMomentary current through the breaker B=%dA\n'',abs(ImomB));
+
+
+ //(d) to compute current to be interrupted by breaker in 5 cycles
+
+ XdM2=(XdM2*mvab)/Mmva ;//perunit transient impedance of each motor
+
+ IscB=(2*(1/XdM2))+(1/(XdG+Xt1+Xt2+Xtl));
+
+ IscB=IscB*Ibase;
+
+ ImomB=1.1*IscB;
+
+ printf(''\nCurrent to be interrupted by breaker B in five cycles=%dA\n'',abs(ImomB));'
- model: saveAPI.gallery
- pk: 773
+ pk: 152
fields:
save_id: gallery151
name: example_9_3
description: 'Modern Power System Analysis (Author: D. P. Kothari And I. J. Nagrath),
9) Symmetrical Fault Analysis, 9.3) Subtransient Current Calculation'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 83
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.5" title="example_9_3"><!--Xcos - 1.0 - scilab-5.5.2
@@ -172773,14 +196520,79 @@
as="geometry" height="8.0" width="8.0" x="16.0" y="-8.0"/></ImplicitOutputPort></root></mxGraphModel><mxCell
as="defaultParent" id="-487ef5e3:131246c8237:-8000" parent="-487ef5e3:131246c8237:-7fff"/></XcosDiagram>
media: gallery151.png
+ script_dump: '//Chapter 9
+
+ //Example 9.3
+
+ //page 340
+
+ //To calculate subtransient current in Generator,Motor and fault
+
+ mvab=25;
+
+ kvb=11;
+
+ Vo=10.6/kvb; //PU Prefault voltage
+
+ printf(''\nPrefault Voltage = %0.4fpu\n'',Vo);
+
+
+ Load=15/mvab; //load PU with 0.8pf leading
+
+ Io=(Load/(Vo*0.8))*(cosd(36.9)+%i*sind(36.9)); //Prefault current
+
+ printf(''\nPrefault current = %0.4f at %0.1f deg PU'',abs(Io),atand(imag(Io)/real(Io)));
+
+
+ Eg=Vo+(%i*0.45*Io); //voltage behind subtransient reactance(generator)
+
+ printf(''\n\nVoltage behind subtransient reactance(Generator) = %0.4f+j%0.2f
+ pu\n'''''',real(Eg),imag(Eg));
+
+
+ Em=Vo-(%i*0.15*Io); //voltage behind subtransient reactance(motor)
+
+ printf(''\nVoltage behind subtransient reactance(Motor) = %0.4f-j%0.4f pu'',real(Em),abs(imag(Em)));
+
+
+ Ig=Eg/(%i*0.45); //under fault condition
+
+ Im=Em/(%i*0.15); //under fault condition
+
+ printf(''\n\nUnder Faulted condition \n Ig""=%0.4f-j%0.4f pu'',real(Ig),abs(imag(Ig)));
+
+ printf(''\n Im""=%0.4f-j%0.4f pu'',real(Im),abs(imag(Im)));
+
+ If=Ig+Im; //Current in fault
+
+ printf(''\n\nCurrent in fault= -j%0.4f pu'',abs(imag(If)));
+
+
+ Ib=(mvab*1000/(sqrt(3)*11)); //Base current
+
+ //Actual Currents
+
+ printf("\n\nNow");
+
+ Ig=Ig*Ib
+
+ Im=Im*Ib
+
+ If=If*Ib
+
+ printf(''\nIg""= %0.1f-j%0.1f A'',real(Ig),abs(imag(Ig)));
+
+ printf(''\nIm""= %0.1f-j%0.1f A'',real(Im),abs(imag(Im)));
+
+ printf(''\nIf= -j%d A'',abs(imag(If)));'
- model: saveAPI.gallery
- pk: 774
+ pk: 153
fields:
save_id: gallery152
name: example_9_4
description: 'Modern Power System Analysis (Author: D. P. Kothari And I. J. Nagrath),
9) Symmetrical Fault Analysis, 9.4) Maximum MVA Calculation'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 83
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.5" title="example_9_4"><!--Xcos - 1.0 - scilab-5.5.2
@@ -173909,14 +197721,75 @@
as="geometry" height="8.0" width="8.0" x="16.0" y="-8.0"/></ImplicitOutputPort></root></mxGraphModel><mxCell
as="defaultParent" id="-487ef5e3:131246c8237:-7cc8" parent="-487ef5e3:131246c8237:-7cc7"/></XcosDiagram>
media: gallery152.png
+ script_dump: '//Chapter 9
+
+ //Example 9.4
+
+ //page 345
+
+ //To calculate maximum MVA
+
+ mvab=50;
+
+ kvb=6.6;
+
+ mvaA=40;
+
+ mvaB=50;
+
+ mvaC=25;
+
+ feeder_impedance=((0.06+%i*0.12)*mvab)/(kvb^2)
+
+
+ Gen_A_reactance=(%i*0.1*mvab/mvaA);
+
+ Gen_B_reactance=(%i*0.1*mvab/mvaB);
+
+ Gen_C_reactance=(%i*0.1*mvab/mvaC);
+
+
+ printf(''\nGenerator A reactance = j%0.3f pu'',abs(Gen_A_reactance));
+
+ printf(''\nGenerator B reactance = j%0.3f pu'',abs(Gen_B_reactance));
+
+ printf(''\nGenerator C reactance = j%0.3f pu'',abs(Gen_C_reactance));
+
+
+ Reactor_A_reactance=(%i*0.12*mvab/mvaA);
+
+ Reactor_B_reactance=(%i*0.12*mvab/mvaB);
+
+ Reactor_C_reactance=(%i*0.12*mvab/mvaC);
+
+
+ printf(''\nReactor A reactance = j%0.3f pu'',abs(Reactor_A_reactance));
+
+ printf(''\nReactor B reactance = j%0.3f pu'',abs(Reactor_B_reactance));
+
+ printf(''\nReactor C reactance = j%0.3f pu'',abs(Reactor_C_reactance));
+
+
+ function resistance=parallel(r1,r2)
+
+ resistance=(r1*r2/(r1+r2));
+
+ endfunction
+
+
+ Z=(feeder_impedance)+parallel(%i*0.125,(%i*0.15 + parallel(%i*0.22,%i*0.44)));
+
+ scmva=(1/abs(Z))*mvab;
+
+ printf("\n\nSC MVA = %d MVA",scmva);'
- model: saveAPI.gallery
- pk: 775
+ pk: 154
fields:
save_id: gallery153
name: example_9_5
description: 'Modern Power System Analysis (Author: D. P. Kothari And I. J. Nagrath),
9) Symmetrical Fault Analysis, 9.5) Short Circuit Solution'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 83
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="0.5" title="example_9_5"><!--Xcos - 1.0 - scilab-5.5.2
@@ -175067,14 +198940,80 @@
as="geometry" height="8.0" width="8.0" x="16.0" y="60.0"/></ImplicitOutputPort></root></mxGraphModel><mxCell
as="defaultParent" id="-487ef5e3:131246c8237:-799b" parent="-487ef5e3:131246c8237:-799a"/></XcosDiagram>
media: gallery153.png
+ script_dump: '//Chapter 9
+
+ //Example 9.5
+
+ //page 347
+
+ //To calculate short circuit solution
+
+ //referring to figures 9.19 in the text book,we get directly the fault current
+
+ V4o=1.0;
+
+ Zf=%i*0.13560;
+
+ If=V4o/Zf;
+
+ printf(''\nIf= -j%0.5f pu\n\n'',abs(If));
+
+
+ //From Fig9.19d
+
+ I1=If*((%i*0.19583)/(%i*0.37638));
+
+ I2=If*((%i*0.18055)/(%i*0.37638));
+
+ printf(''I1 = -j%0.5f pu \n\nI2 = -j%0.5f pu\n\n'',abs(I1),abs(I2));
+
+
+ //voltage changes for bus 1,2 and 3
+
+ deltaV1=0-(%i*0.15)*I1;
+
+ deltaV2=0-(%i*0.15)*I2;
+
+ printf(''DeltaV1=%0.5f pu\n\nDeltaV2=%0.5f pu\n\n'',deltaV1,deltaV2);
+
+
+ //reffering to book
+
+ V1f=1+deltaV1;
+
+ V2f=1+deltaV2;
+
+ printf(''V1f= %0.5f pu\n\nV2f=%0.5f pu\n\n'',V1f,V2f);
+
+ I13=(V1f-V2f)/(%i*0.15+%i*0.1);
+
+ printf(''I13=j%0.5f pu\n\n'',abs(I13));
+
+ deltaV3=0-((%i*0.15)*(I1)+(%i*0.15)*(I13));
+
+ Vf3=1+deltaV3;
+
+ printf(''DeltaV3=%0.5f pu\n\n'',deltaV3);
+
+ printf(''Vf3=%0.5f pu\n\n'',Vf3);
+
+ Vf4=0;
+
+ printf(''Vf4=%d\n\n'',Vf4);
+
+ //short circuit MVA at bus 4
+
+ SC_MVA_4=abs(If)*100;
+
+ printf(''Short circuit MVA at bus4 =%0.3f MVA'',SC_MVA_4);'
- model: saveAPI.gallery
- pk: 776
+ pk: 155
fields:
save_id: gallery154
name: example_9_7
description: 'Modern Power System Analysis (Author: D. P. Kothari And I. J. Nagrath),
9) Symmetrical Fault Analysis, 9.7) Current Injection Method'
- save_time: 2025-01-23 16:04:57+00:00
+ save_time: 2025-03-17 15:49:09+00:00
book: 83
data_dump: <?xml version="1.0" encoding="UTF-8"?><XcosDiagram background="-1"
finalIntegrationTime="6.0" title="example_9_7"><!--Xcos - 1.0 - scilab-5.5.2
@@ -176287,3 +200226,37 @@
as="geometry" height="40.0" width="40.0" x="600.0" y="350.0"/></TextBlock></root></mxGraphModel><mxCell
as="defaultParent" id="75289c83:1315698632f:-8000" parent="75289c83:1315698632f:-7fff"/></XcosDiagram>
media: gallery154.png
+ script_dump: '//Chapter 9
+
+ //Example 9.7
+
+ //page 355
+
+ //To evaluate Zbus using Current Injection method
+
+
+ disp("We can approach this problem using XCOS simulation")
+
+ disp("In this simulation");
+
+ disp("1)For injecting unit current at bus1 keeping bus2 open circuit,we use
+ a current source of 1 unit which is switched on from t=0 to t=2. During this
+ period we can observe the voltage waveforms of V1 and V2 and compare with the
+ results given in the textbook");
+
+ disp("2)For injecting unit current at bus2 keeping bus1 open circuit,we use
+ a current source of 1 unit which is switched on from t=4 to t=6. During this
+ period we can observe the voltage waveforms of V1 and V2 and compare with the
+ results given in the textbook");
+
+
+ Z11=7;
+
+ Z21=4;
+
+ Z12=Z21;
+
+ Z22=6;
+
+
+ Zbus=[Z11 Z12;Z21 Z22]'