Our server costs ~$56 per month to run. Please consider donating or becoming a Patron to help keep the site running. Help us gain new members by following us on Twitter and liking our page on Facebook!
Current time: April 23, 2024, 2:39 am

Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to find the point on the root locus with a certain damping in Octave
#1
How to find the point on the root locus with a certain damping in Octave
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?
Reply
#2
RE: How to find the point on the root locus with a certain damping in Octave
I am shocked you are within two tests of earning your diploma.  

Seems you should finish but we aren't your personal tutors.
  
“If you are the smartest person in the room, then you are in the wrong room.” — Confucius
                                      
Reply
#3
RE: How to find the point on the root locus with a certain damping in Octave
I don’t recall being assigned to help you with your schoolwork.

Boru 

(Not that I’d be much help, anyroad.)
‘But it does me no injury for my neighbour to say there are twenty gods or no gods. It neither picks my pocket nor breaks my leg.’ - Thomas Jefferson
Reply
#4
RE: How to find the point on the root locus with a certain damping in Octave
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?
Reply
#5
RE: How to find the point on the root locus with a certain damping in Octave
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).
Reply
#6
RE: How to find the point on the root locus with a certain damping in Octave
(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
‘But it does me no injury for my neighbour to say there are twenty gods or no gods. It neither picks my pocket nor breaks my leg.’ - Thomas Jefferson
Reply
#7
RE: How to find the point on the root locus with a certain damping in Octave
(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?
Reply
#8
RE: How to find the point on the root locus with a certain damping in Octave
Was your sense of humor surgically removed at birth?
  
“If you are the smartest person in the room, then you are in the wrong room.” — Confucius
                                      
Reply
#9
RE: How to find the point on the root locus with a certain damping in Octave
(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.
Reply
#10
RE: How to find the point on the root locus with a certain damping in Octave
Tutoring from me is $100 an hour, payable in advance.
Reply



Possibly Related Threads...
Thread Author Replies Views Last Post
  A Technology That Dominionists Will Find Useful Secular Elf 6 1596 June 29, 2015 at 10:48 am
Last Post: Nope



Users browsing this thread: 1 Guest(s)