Posts: 2020
Threads: 133
Joined: July 26, 2017
Reputation:
5
How to find the point on the root locus with a certain damping in Octave
May 13, 2023 at 12:03 pm
I don't have MatLab installed on my computer (and I don't know how to install it), so I am trying to do a laboratory exercise in Control Engineering in Octave. In that laboratory exercise, I am supposed to find the gain at the point on the root locus where damping is equal to 0.7. Octave does support the `rlocus` command, however, in the window where the root locus is opened, in the "Tools" menu, there is no "Data Tips" option (that the instructions for the laboratory exercise advise us to use). So, how can I find the point on the root locus where the damping is equal to 0.7 in Octave? Are you supposed to somehow get an array of the coordinates of all the points on the root locus and find the one for which the cos(atan(y/x)) (I think that's how the formula goes, but I am not sure) is the closest to 0.7, or?
I am not very familiar with the MatLab/Octave programming language. I was thinking about attempting to do that in the language I am familiar with, such as JavaScript. Finding a pair of numbers from some list (the coordinates of points on the root locus) for which the damping (if damping associated with some point on root locus is indeed equal to cos(atan(y/x))) is the closest to 0.7 is trivial in JavaScript. So is telling the gain associated with that point. The formula for that involves absolute diffences between complex numbers, but those can trivially be replaced by Pythagorean Theorem. But telling whether some randomly chosen point indeed belongs to the root locus is not trivial to do in JavaScript. It is not obvious how to implement those formulas (the amplitude and phase condition) in a language that doesn't support complex numbers.
In all seriousness, this university is killing me. I am considering dropping out even if I only have two tests left to the diploma. What do you think, by deciding not to drop out, am I committing the Sunk Cost Fallacy?
Posts: 16481
Threads: 127
Joined: July 10, 2013
Reputation:
65
RE: How to find the point on the root locus with a certain damping in Octave
May 13, 2023 at 12:11 pm
(This post was last modified: May 13, 2023 at 12:42 pm by arewethereyet.)
I am shocked you are within two tests of earning your diploma.
Seems you should finish but we aren't your personal tutors.
Posts: 46145
Threads: 539
Joined: July 24, 2013
Reputation:
109
RE: How to find the point on the root locus with a certain damping in Octave
May 13, 2023 at 12:41 pm
I don’t recall being assigned to help you with your schoolwork.
Boru
(Not that I’d be much help, anyroad.)
‘I can’t be having with this.’ - Esmeralda Weatherwax
Posts: 2020
Threads: 133
Joined: July 26, 2017
Reputation:
5
RE: How to find the point on the root locus with a certain damping in Octave
May 14, 2023 at 5:49 am
(This post was last modified: May 14, 2023 at 5:58 am by FlatAssembler.
Edit Reason: fixed a typo
)
OK, this C++ program I've made:
Code: #include <algorithm>
#include <complex>
#include <fstream>
#include <iostream>
#include <vector>
double prigusenje(std::complex<double> s) { return std::cos(std::arg(-s)); }
int main() {
using namespace std;
double potrebno_prigusenje = 0.7;
vector<complex<double>> nule{-0.003515, -1.754},
polovi{0, -20 * 1.754, -1.754, -0.1986, -0.003515};
vector<complex<double>> KMK;
vector<double> argumenti, prigusenja;
double epsilon = 0.001;
for (double x = -1; x < 1; x += epsilon)
for (double y = -4; y < 4; y += epsilon) {
complex<double> s(x, y);
complex<double> brojnik = 1, nazivnik = 1;
for (auto nula : nule)
brojnik *= s - nula;
for (auto pol : polovi)
nazivnik *= s - pol;
complex<double> Gs = brojnik / nazivnik;
if (abs(arg(Gs) * (180 / M_PI) - 180) < 3 * epsilon ||
abs(arg(Gs) * (180 / M_PI) + 180) < 3 * epsilon) {
KMK.push_back(s);
argumenti.push_back(arg(Gs) * (180 / M_PI));
prigusenja.push_back(prigusenje(s));
}
}
ofstream datoteka("KMK.txt");
datoteka << "x\ty\tphi\tdzeta\n";
for (int i = 0; i < KMK.size(); i++) {
complex<double> tocka = KMK[i];
double argument = argumenti[i];
double prigusenje = prigusenja[i];
datoteka << tocka.real() << '\t' << tocka.imag() << '\t' << argument << '\t'
<< prigusenje << '\n';
}
datoteka.close();
complex<double> najbolji = *min_element(
KMK.begin(), KMK.end(),
[potrebno_prigusenje](complex<double> prvi, complex<double> drugi) {
return abs(prigusenje(prvi) - potrebno_prigusenje) <
abs(prigusenje(drugi) - potrebno_prigusenje);
});
cout << "prigusenje = " << prigusenje(najbolji) << endl;
cout << "frekvencija = " << abs(najbolji.imag()) << endl;
cout << "x = " << najbolji.real() << endl;
double brojnik = 1, nazivnik = 1;
for (auto pol : polovi)
brojnik *= abs(najbolji - pol);
for (auto nula : nule)
nazivnik *= abs(najbolji - nula);
double pojacanje = brojnik / nazivnik;
cout << "pojacanje = " << pojacanje << endl;
}
It prints out the following:
Code: prigusenje = 0.689481
frekvencija = 0.104
x = -0.099
pojacanje = 0.723288
So, allegedly, for the gain of 0.723288, the damping is equal to 0.689481 (very close to the required damping of 0.7), and the frequency is 0.104 rad/sec. How do I check whether that's true?
Posts: 2020
Threads: 133
Joined: July 26, 2017
Reputation:
5
RE: How to find the point on the root locus with a certain damping in Octave
May 14, 2023 at 6:02 am
In C++, it's not nearly as easy to draw diagrams as it is in JavaScript, but it's very easy to deal with complex numbers (which is very difficult in JavaScript).
Posts: 46145
Threads: 539
Joined: July 24, 2013
Reputation:
109
RE: How to find the point on the root locus with a certain damping in Octave
May 14, 2023 at 6:44 am
(May 14, 2023 at 5:49 am)FlatAssembler Wrote: OK, this C++ program I've made:
Code: #include <algorithm>
#include <complex>
#include <fstream>
#include <iostream>
#include <vector>
double prigusenje(std::complex<double> s) { return std::cos(std::arg(-s)); }
int main() {
using namespace std;
double potrebno_prigusenje = 0.7;
vector<complex<double>> nule{-0.003515, -1.754},
polovi{0, -20 * 1.754, -1.754, -0.1986, -0.003515};
vector<complex<double>> KMK;
vector<double> argumenti, prigusenja;
double epsilon = 0.001;
for (double x = -1; x < 1; x += epsilon)
for (double y = -4; y < 4; y += epsilon) {
complex<double> s(x, y);
complex<double> brojnik = 1, nazivnik = 1;
for (auto nula : nule)
brojnik *= s - nula;
for (auto pol : polovi)
nazivnik *= s - pol;
complex<double> Gs = brojnik / nazivnik;
if (abs(arg(Gs) * (180 / M_PI) - 180) < 3 * epsilon ||
abs(arg(Gs) * (180 / M_PI) + 180) < 3 * epsilon) {
KMK.push_back(s);
argumenti.push_back(arg(Gs) * (180 / M_PI));
prigusenja.push_back(prigusenje(s));
}
}
ofstream datoteka("KMK.txt");
datoteka << "x\ty\tphi\tdzeta\n";
for (int i = 0; i < KMK.size(); i++) {
complex<double> tocka = KMK[i];
double argument = argumenti[i];
double prigusenje = prigusenja[i];
datoteka << tocka.real() << '\t' << tocka.imag() << '\t' << argument << '\t'
<< prigusenje << '\n';
}
datoteka.close();
complex<double> najbolji = *min_element(
KMK.begin(), KMK.end(),
[potrebno_prigusenje](complex<double> prvi, complex<double> drugi) {
return abs(prigusenje(prvi) - potrebno_prigusenje) <
abs(prigusenje(drugi) - potrebno_prigusenje);
});
cout << "prigusenje = " << prigusenje(najbolji) << endl;
cout << "frekvencija = " << abs(najbolji.imag()) << endl;
cout << "x = " << najbolji.real() << endl;
double brojnik = 1, nazivnik = 1;
for (auto pol : polovi)
brojnik *= abs(najbolji - pol);
for (auto nula : nule)
nazivnik *= abs(najbolji - nula);
double pojacanje = brojnik / nazivnik;
cout << "pojacanje = " << pojacanje << endl;
}
It prints out the following:
Code: prigusenje = 0.689481
frekvencija = 0.104
x = -0.099
pojacanje = 0.723288
So, allegedly, for the gain of 0.723288, the damping is equal to 0.689481 (very close to the required damping of 0.7), and the frequency is 0.104 rad/sec. How do I check whether that's true?
Try a little tenderness?
Boru
‘I can’t be having with this.’ - Esmeralda Weatherwax
Posts: 2020
Threads: 133
Joined: July 26, 2017
Reputation:
5
RE: How to find the point on the root locus with a certain damping in Octave
May 14, 2023 at 7:37 am
(May 14, 2023 at 6:44 am)BrianSoddingBoru4 Wrote: (May 14, 2023 at 5:49 am)FlatAssembler Wrote: OK, this C++ program I've made:
Code: #include <algorithm>
#include <complex>
#include <fstream>
#include <iostream>
#include <vector>
double prigusenje(std::complex<double> s) { return std::cos(std::arg(-s)); }
int main() {
using namespace std;
double potrebno_prigusenje = 0.7;
vector<complex<double>> nule{-0.003515, -1.754},
polovi{0, -20 * 1.754, -1.754, -0.1986, -0.003515};
vector<complex<double>> KMK;
vector<double> argumenti, prigusenja;
double epsilon = 0.001;
for (double x = -1; x < 1; x += epsilon)
for (double y = -4; y < 4; y += epsilon) {
complex<double> s(x, y);
complex<double> brojnik = 1, nazivnik = 1;
for (auto nula : nule)
brojnik *= s - nula;
for (auto pol : polovi)
nazivnik *= s - pol;
complex<double> Gs = brojnik / nazivnik;
if (abs(arg(Gs) * (180 / M_PI) - 180) < 3 * epsilon ||
abs(arg(Gs) * (180 / M_PI) + 180) < 3 * epsilon) {
KMK.push_back(s);
argumenti.push_back(arg(Gs) * (180 / M_PI));
prigusenja.push_back(prigusenje(s));
}
}
ofstream datoteka("KMK.txt");
datoteka << "x\ty\tphi\tdzeta\n";
for (int i = 0; i < KMK.size(); i++) {
complex<double> tocka = KMK[i];
double argument = argumenti[i];
double prigusenje = prigusenja[i];
datoteka << tocka.real() << '\t' << tocka.imag() << '\t' << argument << '\t'
<< prigusenje << '\n';
}
datoteka.close();
complex<double> najbolji = *min_element(
KMK.begin(), KMK.end(),
[potrebno_prigusenje](complex<double> prvi, complex<double> drugi) {
return abs(prigusenje(prvi) - potrebno_prigusenje) <
abs(prigusenje(drugi) - potrebno_prigusenje);
});
cout << "prigusenje = " << prigusenje(najbolji) << endl;
cout << "frekvencija = " << abs(najbolji.imag()) << endl;
cout << "x = " << najbolji.real() << endl;
double brojnik = 1, nazivnik = 1;
for (auto pol : polovi)
brojnik *= abs(najbolji - pol);
for (auto nula : nule)
nazivnik *= abs(najbolji - nula);
double pojacanje = brojnik / nazivnik;
cout << "pojacanje = " << pojacanje << endl;
}
It prints out the following:
Code: prigusenje = 0.689481
frekvencija = 0.104
x = -0.099
pojacanje = 0.723288
So, allegedly, for the gain of 0.723288, the damping is equal to 0.689481 (very close to the required damping of 0.7), and the frequency is 0.104 rad/sec. How do I check whether that's true?
Try a little tenderness?
Boru
What do you mean?
Posts: 16481
Threads: 127
Joined: July 10, 2013
Reputation:
65
RE: How to find the point on the root locus with a certain damping in Octave
May 14, 2023 at 7:42 am
Was your sense of humor surgically removed at birth?
Posts: 2020
Threads: 133
Joined: July 26, 2017
Reputation:
5
RE: How to find the point on the root locus with a certain damping in Octave
May 14, 2023 at 11:25 am
(May 14, 2023 at 7:42 am)arewethereyet Wrote: Was your sense of humor surgically removed at birth?
Well, I do have some brain damage, presumably caused by dyspnea shortly after birth. It's in the motorics part of the brain, so it shouldn't affect my sense of humor, but who knows.
Posts: 2412
Threads: 5
Joined: January 3, 2018
Reputation:
22
RE: How to find the point on the root locus with a certain damping in Octave
May 14, 2023 at 7:29 pm
Tutoring from me is $100 an hour, payable in advance.
|