Skocz do zawartości

simba92

Użytkownicy
  • Zawartość

    93
  • Rejestracja

  • Ostatnio

  • Wygrane dni

    3

simba92 zajął 1. miejsce w rankingu.
Data osiągnięcia: 8 listopada 2019.

Treści użytkownika simba92 zdobyły tego dnia najwięcej polubień!

Informacje

  • Płeć
    Mężczyzna
  • Lokalizacja
    Bydgoszcz

Ostatnio na profilu byli

Blok z ostatnio odwiedzającymi jest wyłączony i nie jest wyświetlany innym użytkownikom.

Osiągnięcia użytkownika simba92

Entuzjasta

Entuzjasta (7/19)

  • Za 5 postów
  • Za 25 postów
  • Młodszy Juror
  • Wschodząca gwiazda
  • To już rok!

Odznaki

25

Reputacja

  1. Cześć! Odświeżam temat, może ktoś bardziej doświadczony będzie w stanie mi pomóc lub coś zasugerować. Swoją aplikacje w C# napisałem w oparciu o przedstawiony artykuł. Aplikacja odbiera ramki danych wysyłanych na port COM co 200 ms . Problem z którym się zmagam polega na zawieszaniu się aplikacji podczas próby zamknięcia portu. W kodzie z artykułu dane odbierane są podczas obsługi zdarzenia w oparciu o delegata i funkcję na którą wskazuje. Zamknięcie portu odbywa się za pomocą pictureBoxa i przerwania od niego, w którym port jest zamykany. Wszystko tak samo jak w głównym programie Form1.cs. Nie mam zbyt dużego doświadczenia w programowaniu w C#, próbowałem już kilku rozwiązań z internetu. Generalnie z tego co czytałem problem dot. lub jest związany z obsługą zdarzeń od zamykania portu i formularza, trochę się w tym gubię wiec proszę o wyrozumiałość. W jaki sposób ustrzec aplikacje przed zawieszaniem się ??? Pozdrawiam i dziękuje za wszelkie wskazówki !!! PS : może ktoś tu zajrzy 🙂 //wygenerowane using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; //moje using System.IO.Ports; namespace TutorialCOM { public delegate void Delegat(); public partial class tutorialCOM : Form { //zmienne użytkownika SerialPort port; Delegat moj_del; public tutorialCOM() { InitializeComponent(); //inicjalizacja zmiennej port z domyślnymi wartościami port = new SerialPort(); //ustawienie timeoutów aby program się nie wieszał port.ReadTimeout = 500; port.WriteTimeout = 500; Opcje.Enter += new EventHandler(Opcje_Enter); port.DataReceived += new SerialDataReceivedEventHandler(DataRecievedHandler); moj_del = new Delegat(WpiszOdebrane); } private void DataRecievedHandler(object sender, SerialDataReceivedEventArgs e) { rtbTerminal.Invoke(moj_del); } private void WpiszOdebrane() { DodajKolorowy(rtbTerminal, port.ReadByte().ToString("X") + " ", System.Drawing.Color.Blue); } private void DodajKolorowy(System.Windows.Forms.RichTextBox RichTextBox, string Text, System.Drawing.Color Color) { var StartIndex = RichTextBox.TextLength; RichTextBox.AppendText(Text); var EndIndex = RichTextBox.TextLength; RichTextBox.Select(StartIndex, EndIndex - StartIndex); RichTextBox.SelectionColor = Color; RichTextBox.ScrollToCaret(); } void Opcje_Enter(object sender, EventArgs e) { //aktualizacja list this.cbName.Items.Clear(); this.cbParity.Items.Clear(); this.cbStop.Items.Clear(); foreach (String s in SerialPort.GetPortNames()) this.cbName.Items.Add(s); foreach (String s in Enum.GetNames(typeof(Parity))) this.cbParity.Items.Add(s); foreach (String s in Enum.GetNames(typeof(StopBits))) this.cbStop.Items.Add(s); //aktualizacja nazw cbName.Text = port.PortName.ToString(); cbBaud.Text = port.BaudRate.ToString(); cbData.Text = port.DataBits.ToString(); cbParity.Text = port.Parity.ToString(); cbStop.Text = port.StopBits.ToString(); } private void butSend_Click(object sender, EventArgs e) { if (port.IsOpen) { DodajKolorowy(rtbTerminal, ((Int32)numericSend.Value).ToString("X") + " ", System.Drawing.Color.Black); Byte[] tosend = { (Byte) numericSend.Value}; port.Write(tosend, 0, 1); } else MessageBox.Show("Aby wysłać bajt musisz ustanowić połączenie"); } private void butDomyslne_Click(object sender, EventArgs e) { this.cbName.Text = "COM8"; this.cbBaud.Text = "115200"; this.cbData.Text = "8"; this.cbParity.Text = "None"; this.cbStop.Text = "One"; } private void butCancel_Click(object sender, EventArgs e) { cbName.Text = port.PortName.ToString(); cbBaud.Text = port.BaudRate.ToString(); cbData.Text = port.DataBits.ToString(); cbParity.Text = port.Parity.ToString(); cbStop.Text = port.StopBits.ToString(); } private void pbStatus_Click(object sender, EventArgs e) // bylo FormClosingEventArgs { //jeżeli połączenie jest aktywne to je kończymy, zmieniamy kolor na red i zmieniamy napis if (port.IsOpen) { pbStatus.BackColor = Color.Red; port.Close(); labStatus.Text = "Brak połączenia (teraz można zmieniać opcje połączenia)"; DodajKolorowy(rtbTerminal, "\nZakończono połączenie z " + port.PortName + "\n", System.Drawing.Color.Orange); } //w przeciwnym wypadku włączamy połączenie, zmieniamy kolor na zielony i zmieniamy napis else { //połączenie może nie być możliwe dlatego należy się zabezpieczyć na wypadek błędu try { //najpierw przepisujemy do portu parametry z opcji port.PortName = this.cbName.Text; port.BaudRate = Int32.Parse(this.cbBaud.Text); port.DataBits = Int32.Parse(this.cbData.Text); port.Parity = (Parity)Enum.Parse(typeof(Parity), this.cbParity.Text); port.StopBits = (StopBits)Enum.Parse(typeof(StopBits), this.cbStop.Text); //a następnie uruchamiamy port port.Open(); //po uruchomieniu zmieniamy elementy graficzne interfejsu pbStatus.BackColor = System.Drawing.Color.Green; labStatus.Text = "Aktywne połączenie (port:" + port.PortName.ToString() + ", prędkość: " + port.BaudRate.ToString() + ", bity danych: " + port.DataBits.ToString() + "\n bity stopu: " + port.StopBits.ToString() + ", parzystość: " + port.Parity.ToString() + ")"; DodajKolorowy(rtbTerminal, "Rozpoczęto połączenie z " + port.PortName + "\n", System.Drawing.Color.Orange); } //jeżeli nastąpi błąd to go przechwycimy i wyświetlimy stosowny komunikat catch(Exception exc) { MessageBox.Show("Błąd połączenia:\n" + exc.Message); } } } private void butClear_Click(object sender, EventArgs e) { } private void rtbTerminal_TextChanged(object sender, EventArgs e) { } } }
  2. @FlyingDutch tak jak pisałeś zapewne w moim mikrokontrolerze mógł się uszkodzić kontroler interfejsu SWD lub wewn. pamięć flash. W płytce mam zworki od BOOT0 i BOOT1 (docelowo robot miał być programowany opcjonalnie z karty micro SD lub ew. przez BT ( HC06(Master + Slave) + konwerter USB-UART), więc rozwiązanie programowania przez bootloader mógłbym przetestować i napewno zrobię to w przyszłości. Z powodu jednak braku czasu na, którym mi zależy zdecydowałem się wylutować stary mikrokontroler i wlutować nowy. Efekt jest taki, że wymieniłem procesor i wgrałem bez problemów testowy program z migającą diodą, hula aż miło 🙂 Dziękuje @Lukaszm i @FlyingDutch wam za szybką pomoc, wzbogaciłem się o nową wiedzę i doświadczenie.
  3. Przewody nie są uszkodzone, ponieważ programator połączył się z procesorem przez ST-LINK Utility, załączam screeny : Dodatkowy screen z 2 programatora (płytka nucleo - w trybie st link - tj. zworki zdjęte) : Pomimo realizacji następujących kroków : erase chip + zmiana ustawień tj. Software Reset - problem z wgraniem programu jest ten sam ... EDIT : jest jeszcze możliwość update' u firmware ale z tego co widzę wersja V2.J27.M15 STM32 Debug+Mass storage jest (NOWSZA ) w porównaniu do V2.J25.M13 (STARSZEJ) wg. indeksów.
  4. Cześć ! Od długie czasu bez żadnych problemów programowałem mikrokontroler STM32f103vct6 przez interfejs SWD i ku mojemu przerażeniu nie mogę go ponownie zaprogramować. W konsoli widnieje następująca lista komunikatów : Open On-Chip Debugger 0.10.0-dev-00005-g4030e1c-dirty (2017-10-24-08:00) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html none separate Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD adapter_nsrst_delay: 100 adapter speed: 950 kHz Info : clock speed 950 kHz Info : STLINK v2 JTAG v27 API v2 M v15 VID 0x0483 PID 0x374B Info : using stlink api v2 Info : Target voltage: 3.243073 Info : Stlink adapter speed set to 950 kHz Info : STM32F103VCTx.cpu: hardware has 6 breakpoints, 4 watchpoints Info : Stlink adapter speed set to 950 kHz adapter speed: 950 kHz STM32F103VCTx.cpu: target state: halted target halted due to debug-request, current mode: Thread xPSR: 0x01000000 pc: 0x08003328 msp: 0x2000c000 Info : Stlink adapter speed set to 4000 kHz adapter speed: 4000 kHz ** Programming Started ** auto erase enabled Info : device id = 0x10036414 Info : flash size = 256kbytes STM32F103VCTx.cpu: target state: halted target halted due to breakpoint, current mode: Thread xPSR: 0x41000000 pc: 0x2000003a msp: 0x2000c000 wrote 22528 bytes from file Debug/HUSARZ_SLAM_ver1.0.elf in 1.034059s (21.275 KiB/s) ** Programming Finished ** ** Verify Started ** STM32F103VCTx.cpu: target state: halted target halted due to breakpoint, current mode: Thread xPSR: 0x61000000 pc: 0x2000002e msp: 0x2000c000 Error: checksum mismatch - attempting binary compare diff 0 address 0x080032da. Was 0xff instead of 0x10 diff 1 address 0x080032db. Was 0xf7 instead of 0x21 diff 2 address 0x080032dc. Was 0xff instead of 0x07 diff 3 address 0x080032dd. Was 0xff instead of 0x48 diff 4 address 0x080032de. Was 0xff instead of 0xfd diff 5 address 0x080032df. Was 0xff instead of 0xf7 diff 6 address 0x080032e0. Was 0xff instead of 0x18 diff 7 address 0x080032e1. Was 0xff instead of 0xfe diff 8 address 0x080032e2. Was 0xff instead of 0x0a diff 9 address 0x080032e3. Was 0xff instead of 0x20 diff 10 address 0x080032e5. Was 0xff instead of 0xf7 diff 11 address 0x080032e6. Was 0xff instead of 0x2c diff 12 address 0x080032e8. Was 0xff instead of 0x00 diff 13 address 0x080032e9. Was 0xff instead of 0x22 diff 14 address 0x080032ea. Was 0xff instead of 0x10 diff 15 address 0x080032eb. Was 0xff instead of 0x21 diff 16 address 0x080032ec. Was 0xff instead of 0x03 diff 17 address 0x080032ed. Was 0xff instead of 0x48 diff 18 address 0x080032ee. Was 0xff instead of 0xfd diff 19 address 0x080032ef. Was 0xff instead of 0xf7 diff 20 address 0x080032f0. Was 0xff instead of 0x10 diff 21 address 0x080032f1. Was 0xff instead of 0xfe diff 22 address 0x080032f2. Was 0xff instead of 0xfe diff 23 address 0x080032f3. Was 0xff instead of 0xf7 diff 24 address 0x080032f4. Was 0xff instead of 0xd5 diff 25 address 0x080032f5. Was 0xff instead of 0xf8 diff 26 address 0x080032f6. Was 0xff instead of 0x00 diff 27 address 0x080032f7. Was 0xff instead of 0xbf diff 28 address 0x080032f8. Was 0xff instead of 0x80 diff 29 address 0x080032f9. Was 0xff instead of 0xbd diff 30 address 0x080032fa. Was 0xff instead of 0x00 diff 31 address 0x080032fb. Was 0xff instead of 0xbf diff 32 address 0x080032fc. Was 0xff instead of 0x00 diff 33 address 0x080032fd. Was 0xff instead of 0x08 diff 34 address 0x080032fe. Was 0xff instead of 0x01 diff 35 address 0x080032ff. Was 0xff instead of 0x40 diff 36 address 0x08003300. Was 0xff instead of 0x80 diff 37 address 0x08003301. Was 0xff instead of 0xb5 diff 38 address 0x08003302. Was 0xff instead of 0x00 diff 39 address 0x08003303. Was 0xff instead of 0xaf diff 40 address 0x08003304. Was 0xff instead of 0x45 diff 41 address 0x08003305. Was 0xff instead of 0xf2 diff 42 address 0x08003306. Was 0xff instead of 0x55 diff 43 address 0x08003307. Was 0xff instead of 0x50 diff 44 address 0x08003308. Was 0xff instead of 0xfd diff 45 address 0x08003309. Was 0xff instead of 0xf7 diff 46 address 0x0800330a. Was 0xff instead of 0x5c diff 47 address 0x0800330c. Was 0xff instead of 0x03 diff 48 address 0x0800330d. Was 0xff instead of 0x20 diff 49 address 0x0800330e. Was 0xff instead of 0xfd diff 50 address 0x0800330f. Was 0xff instead of 0xf7 diff 51 address 0x08003310. Was 0xff instead of 0x69 diff 52 address 0x08003312. Was 0xff instead of 0x40 diff 53 address 0x08003313. Was 0xff instead of 0xf6 diff 54 address 0x08003315. Was 0xff instead of 0x70 diff 55 address 0x08003316. Was 0xff instead of 0xfd diff 56 address 0x08003317. Was 0xff instead of 0xf7 diff 57 address 0x08003318. Was 0xff instead of 0x75 diff 58 address 0x0800331a. Was 0xff instead of 0xfd diff 59 address 0x0800331b. Was 0xff instead of 0xf7 diff 60 address 0x0800331c. Was 0xff instead of 0x83 diff 61 address 0x0800331e. Was 0xff instead of 0xfd diff 62 address 0x0800331f. Was 0xff instead of 0xf7 diff 63 address 0x08003320. Was 0xff instead of 0x8d diff 64 address 0x08003322. Was 0xff instead of 0x00 diff 65 address 0x08003323. Was 0xff instead of 0xbf diff 66 address 0x08003324. Was 0xff instead of 0x80 diff 67 address 0x08003325. Was 0xff instead of 0xbd diff 68 address 0x08003326. Was 0xff instead of 0x00 diff 69 address 0x08003327. Was 0xff instead of 0x00 diff 70 address 0x08003328. Was 0xff instead of 0x0d diff 71 address 0x08003329. Was 0xff instead of 0x48 diff 72 address 0x0800332a. Was 0xff instead of 0x85 diff 73 address 0x0800332b. Was 0xff instead of 0x46 diff 74 address 0x0800332c. Was 0xff instead of 0x0d diff 75 address 0x0800332d. Was 0xff instead of 0x48 diff 76 address 0x0800332e. Was 0xff instead of 0x0e diff 77 address 0x0800332f. Was 0xff instead of 0x49 diff 78 address 0x08003330. Was 0xff instead of 0x0e diff 79 address 0x08003331. Was 0xff instead of 0x4a diff 80 address 0x08003332. Was 0xff instead of 0x00 diff 81 address 0x08003333. Was 0xff instead of 0x23 diff 82 address 0x08003334. Was 0xff instead of 0x02 diff 83 address 0x08003335. Was 0xff instead of 0xe0 diff 84 address 0x08003336. Was 0xff instead of 0xd4 diff 85 address 0x08003337. Was 0xff instead of 0x58 diff 86 address 0x08003338. Was 0xff instead of 0xc4 diff 87 address 0x08003339. Was 0xff instead of 0x50 diff 88 address 0x0800333a. Was 0xff instead of 0x04 diff 89 address 0x0800333b. Was 0xff instead of 0x33 diff 90 address 0x0800333c. Was 0xff instead of 0xc4 diff 91 address 0x0800333d. Was 0xff instead of 0x18 diff 92 address 0x0800333e. Was 0xff instead of 0x8c diff 93 address 0x0800333f. Was 0xff instead of 0x42 diff 94 address 0x08003340. Was 0xff instead of 0xf9 diff 95 address 0x08003341. Was 0xff instead of 0xd3 diff 96 address 0x08003342. Was 0xff instead of 0x0b diff 97 address 0x08003343. Was 0xff instead of 0x4a diff 98 address 0x08003344. Was 0xff instead of 0x0b diff 99 address 0x08003345. Was 0xff instead of 0x4c diff 100 address 0x08003346. Was 0xff instead of 0x00 diff 101 address 0x08003347. Was 0xff instead of 0x23 diff 102 address 0x08003348. Was 0xff instead of 0x01 diff 103 address 0x08003349. Was 0xff instead of 0xe0 diff 104 address 0x0800334a. Was 0xff instead of 0x13 diff 105 address 0x0800334b. Was 0xff instead of 0x60 diff 106 address 0x0800334c. Was 0xff instead of 0x04 diff 107 address 0x0800334d. Was 0xff instead of 0x32 diff 108 address 0x0800334e. Was 0xff instead of 0xa2 diff 109 address 0x0800334f. Was 0xff instead of 0x42 diff 110 address 0x08003350. Was 0xff instead of 0xfb diff 111 address 0x08003351. Was 0xff instead of 0xd3 diff 112 address 0x08003353. Was 0xff instead of 0xf7 diff 113 address 0x08003354. Was 0xff instead of 0xd9 diff 114 address 0x08003355. Was 0xff instead of 0xfa diff 115 address 0x08003356. Was 0xff instead of 0x00 diff 116 address 0x08003357. Was 0xff instead of 0xf0 diff 117 address 0x08003358. Was 0xff instead of 0x0f diff 118 address 0x08003359. Was 0xff instead of 0xf8 diff 119 address 0x0800335b. Was 0xff instead of 0xf7 diff 120 address 0x0800335c. Was 0xff instead of 0x91 diff 121 address 0x0800335d. Was 0xff instead of 0xfa diff 122 address 0x0800335e. Was 0xff instead of 0xfe diff 123 address 0x0800335f. Was 0xff instead of 0xe7 diff 124 address 0x08003360. Was 0xff instead of 0x00 diff 125 address 0x08003361. Was 0xff instead of 0xc0 diff 126 address 0x08003362. Was 0xff instead of 0x00 diff 127 address 0x08003363. Was 0xff instead of 0x20 More than 128 errors, the rest are not printed. ** Verify Failed ** shutdown command invoked Czy istnieje podejrzenie, że mikrokontroler padł ??? Ostatnia zmiana jaką robiłem dotyczyła zmiany w obsłudze przerwania od zegara SYSTICK z 10 na 5 ms, no ale przecież to nic wielkiego. Wszystko działało wcześniej, zasilanie do robota jest ok, nawet próbowałem programować innym ST-linkiem, to samo ... Nigdy wcześniej nie miałem takiego problemu 😞 o co chodzi z tymi komunikatami w konsoli ??? PS : przeszukuje internet w celu znalezienia odpowiedzi na zaistniałą sytuacje, no ale może jakiś guru z tego forum spojrzy zobaczy i coś zasugeruje. Dzięki !!! PS2 : mógłbym przelutować mikrokontroler na nowy, mam lutownice hotair no ale to już ostateczność...
  5. @Lukaszm wybrałem 9% wypełnienia PWM ze względu na wymaganą małą prędkość robota (Husarz_redSLAM) w trakcie jazdy ( masa robota, łatwość sterowania i realizacji algorytmu SLAM ). Masz racje z częstotliwością, trzeba ją dobrać w odniesieniu do dynamiki obiektu (test silnika na podłożu) i tak jak napisałeś ten czas narastanie będzie dłuższy tj. przebieg wolniejszy stąd więcej próbek. Muszę przeprowadzić testy, dziękuje za wyczerpującą odpowiedź i udzieloną pomoc !!!
  6. @Lukaszm dane do modelowania silnika robiłem, gdy koło kręciło się w powietrzu, więc w sumie źle, bo powinno być ono pod obciążeniem tzn. na podłożu, tak ? Myślę, że koniecznie bo w rzeczywistych warunkach sterowanie będzie abstrakcyjne. 1) częstotliwość pomiarów realizowana była z czasem co 10 ms na próbkę czyli f = 1/T = 1/10ms = 100Hz, za mało ? Z jaką częstotliwością realizować próbkowanie ??? Z większą częstotliwością model będzie bardziej dokładny ? 2) fakt rozdzielczość jest 20 stopni/s. PWM zadawany jest jako liczba całkowita z przedziału 0 - 100, pomimo ,że wartość PWM pierwotnie z algorytmu obliczana jest jako zmienna stało przecinkowa. Rozdzielczość wynika z zakresu PWM, sugerujesz np. zmienić zakres np. z 0-100 na 0-1000 lub więcej dla sygnału PWM i wówczas uzyskanie większej rozdzielczości dla prędkości kątowej ? PS : @Lukaszm dzięki za cenne wskazówki, mam teraz trochę dodatkowych pomysłów do testów dla PID.
  7. Witam ! Chciałbym reaktywować temat i poddać dyskusji wyniki moich prób związanych wysterowaniem silników w moim robocie z wykorzystaniem regulatora PID dla każdego silnika z osobna. Cel był następujący : zadać jednakową prędkość dla obu silników (regulacja PID), aby robot jechał po linii prostej do przodu. Zgodnie z artykułem artykuł regulator PID zrealizowałem następujące kroki dla pierwszego silnika ( silnik HPCB Pololu 150 : 1 ) : 1. Zaimplementowałem kompletny program do obsługi pomiaru prędkości kątowej z silnika za pomocą enkodera magnetycznego wyrażonej w [stopień/sekundę]. a) pełen obrót wynosi 1800 zliczonych impulsów b) prędkość kątowa obliczana jest wg. wzoru : ω [°/s]= ( 360 [°] / 1800 * nTic ) / deltaT : gdzie deltaT = 0.01 , nTic oznacza liczbę impulsów zmierzonych w czasie deltaT 2. Pobrałem dane do matlaba w celu wyznaczenia transmitancji silnika. a) dane obejmują prędkość kątową ω [°/s] dla zadanego sygnału PWM silnika równego 9% wypełnienia w czasie 1s. Dodam, że sygnał PWM generowany jest z częstotliowścią 100kHz zgodną ze sterownikiem TB6612 sterującym silnikiem. Otrzymana transmitancja obiektu : które odpowiedź układu na pobudzenie jednostkowe tj. sygnału PWM jest następujące : Kod z matlaba poniżej : %Wczytywanie danych z pliku dla pomiarów z silnika - motor1L (lewy) datatmp = importdata('pid12.txt'); data = datatmp.data; pwm_input = data(:,1); omega_output = data(:,2); %funkcja iddata przyjmuje: dane wyjsciowe, dane wejsciowe, czas probkowania in_data = iddata(omega_output, pwm_input, 0.01); %funkcja tfest przyjmuje: dane wejsciowo-wyjściowe jako struktura iddata, %ilosc biegunow, ilosc zer, nazwe i wartosc parametru do ustawienia (Ts to %czas probkowania). %estymacja transmitancji obiektu dla in_data motor_tf = tfest(in_data, 1, 1, 'Ts', 0.01); %set(0,'defaultfigureposition',[50 100 600 600]) %figure; %Wektor czasu dt = 0.01; t = 0:dt:1; plot(t, omega_output, 'b') hold on; %wykres odpowiedzi skokowej transmitancji silnika [y, t] = step(motor_tf,1); y = y*9; plot(t, y, 'r') axis([0 1 0 125]) grid on title('Wykres odpowiedzi silnika na zadane pobudzenie PWM = 9%','FontSize',16) xlabel('t [s]','FontSize',14,'FontWeight','bold','Color','black') ylabel('\omega [\circ/s]','FontSize',14,'FontWeight','bold','Color','black') legend({'Odpowiedź rzeczywista silnika - \omega(t)',' Odpowiedź modelu silnika - \omega(t)_{model}'},'Location','southeast',2,'FontSize',16) %,'FontWeight','bold' %%%%%% 3. Znając transmitancje obiektu (silnika) przeszedłem do kroku następnego - wyznaczenia nastaw regulatora PID. Obiekt w pętli zamkniętej : uzyskując przy poniższych nastawach efekty sterowania widoczne na wykresie : 4. Wyznaczone nastawy zaimplementowałem w programie na robocie. Kod programu głównego z odpowiednimi podfunkcjami napisany w C : #include "main.h" //wszystkie biblioteki int main(void) { system_init(); //inicjalizacja całego systemu sterowania dla STM32f103 tj. peryferia, porty itp system_IWDG_RST_check(); iwdg_init(); bluetooth_init(); //inicjalizacja modułu BT do przesyłnia danych do mastera tj. PC encoder_Reset(); //inicjalizacja enkoderów robot_MOTOR1L_controller_PID_init(); // inicjalizacja regulatora PID : jego nastawy int pwmLL; flag = 1; //flaga ustawiona na 1 aby program wszedł do pętli zanim zegar doliczy do 10ms tj. od włączenia robota while(1) { IWDG_ReloadCounter(); if(flag == 1) //program przechodzi do pętli związanej z regulacją PID co 10 ms (zmiana stanu flagi z 0 na 1 w przerwaniu dla zegaru SYSTICK) { encoder_Read(); // pomiar bieżącej prędkości kątowej : motor1L_omega pwmL = robot_MOTOR1L_controller_PID_calculate(120, motor1L_omega); pwmLL = (int)pwmL; robot_drive(pwmLL,0); // sterowanie silnikiem poprzez PWM funkcją robot_drive(lewe koło, prawe koło) flag = 0; } } } Uzyskane efekty działania regulacji PID na robocie są niestety kiepskie, co przejawia się następująco : Po pierwsze dla zadanej prędkości 120 stopni/sekundę regulatora PID koło przyspiesza w nieskończoność... a wynika to z uzyskanych nastaw a) jeżeli uchyb jest duży, a w początkowej fazie tak jest to stała Ki, która wynosi około 3 skutkuje dużym sygnałem sterującym za regulatorem wg. wzoru dla u : float robot_MOTOR1L_controller_PID_calculate(float set_value, float read_value) { float err_d, u; motor1L_PID_error = set_value - read_value; motor1L_PID_error_sum = motor1L_PID_error_sum + motor1L_PID_error; if(motor1L_PID_error_sum > ERR_SUM_MAX) motor1L_PID_error_sum = ERR_SUM_MAX; else if(motor1L_PID_error_sum < -ERR_SUM_MAX) motor1L_PID_error_sum = -ERR_SUM_MAX; err_d = motor1L_PID_error - motor1L_PID_error_last; u = motor1L_KP * motor1L_PID_error + motor1L_KI * motor1L_PID_error_sum + motor1L_KD * err_d; //sygnał sterujący motor1L_PID_error_last = motor1L_PID_error; return u; } tzn. dla danych w czasie t = 0 : motor1L_PID_error = 120, motor1L_PID_error_sum = 0, err_d = motor1L_PID_error=120 u = motor1L_KP * motor1L_PID_error + motor1L_KI * motor1L_PID_error_sum + motor1L_KD * err_d = 0.082957209 * 120 + 2.973355529 * 120 + 0.000466135 * 120 > 360 tu pewien ważny aspekt mojego programu : jeżeli wartość PWM > 100 np. u > 360, to program podaje na sterownik silnika wartość PWM równą PWM_MAX, stąd silnik rozpędza się do nieskończoności... i niestety to się nie chcę ustabilizować. No i teraz pytanie i prośba o wskazówki dot. wyznaczenia nastaw regulatora PID dla silnika. Stworzyłem model silnika według artykułu, dostroiłem regulator w matlabie, przeniosłem uzyskane nastawy na regulator PID na robocie i uzyskałem takie marne wyniki ... co poszło nie tak, co robię źle ??? PS : jeżeli coś jest nie jasne odpowiem chętnie na dodatkowe pytania i szczegóły. Dzięki za każdą cenną wskazówkę !!!
  8. Cześć! Orientuje się ktoś na jakiej warstwie trzeba dać obrys w AUTODESK EAGLE aby płytka zamawiana w PCBWAY miała wycięcia/ inne kształty niż prostokątny? Obrys zaznaczyłem na warstwie DIMENSION. MIlling i nie mam wycięć 😕
  9. Dzięki @Treker ! Jeśli możesz to wystaw jeszcze ocenę w zakładce VOTE, bo projekt tylko polubiłeś 😃 Napewno zamieszczę opis robota na forum i zapewne będzie on dosyć obszerny. Na chwilę obecną robot musi spełniać dwa kluczowe warunki : jechać w linii prostej i podczas obrotu w miejscu nie zmieniać punkt osi wokół, której się obraca ( pisałem o tym problemie wcześniej gdzieś na forum ), więc sprowadza się to do regulatora PID z wartością zadaną będącą prędkością kątową dla każdego koła. @GAndaLF opisał proces modelowania reg PID na forum, symulowałem to i owo w MAtlabie + zaimplementowałem regulator na robocie ale efekty są kiepskie... Niedługo opiszę problem w oddzielnym temacie.
  10. W ostatniej chwili dodałem : https://www.pcbway.com/project/shareproject/W248785ASZ2_HUSARZ.html Serdecznie zachęcam do głosowania na mój projekt!
  11. simba92

    RetroBot

    kamdz tak z ciekawości, w której jesteś klasie ? Jeśli będziesz kiedyś chciał stworzyć bardziej zaawansowaną konstrukcje (nie dla celów edukacyjnych) warto pomyśleć o kwestii aerodynamiki i wagi robota, płytkę drukowaną można zamówić z Chin za małe pieniądze, a ze schematów dostępnych na forum stworzyć np. projekt w Autodesk Eagle lub innym programie. Generalnie forum to kopalnia wiedzy na ten temat, gratuluje konstrukcji !!! Jeśli się nie mylę masz moduł BT na interfejsie UART, więc jakbyś chciał mogę kiedyś pomóc w wolnej chwili z komunikacją ROBOT <-> komputer, którą w pełni zrealizowałem w oparciu o stm32f103 i moduł HC - 05, który jest chyba podobny. Pozdrawiam !!!
  12. Treker tak właśnie myślałem, nigdy nie masz 2 identycznych silników. Jeżeli dobrze rozumiem muszę zapoznać się z tym artykułem : sterowanie robotem klasy (2,0), by zrealizować tak ? Dzięki za szybką odpowiedź !
  13. Cześć ! Na wstępie dodam, że przeglądam całe forum w poszukiwaniu rozwiązania swojego problemu i może gdzieś znajdę odpowiedź. Korzystając jednak z możliwości zaczerpnięcia jakiś wskazówek od bardziej doświadczonych kolegów przedstawię krótko opis problemu z, którym się borykam: Mam robota z napędem różnicowym z dwoma silnikami pololu HPCB 150:1 z zamontowanym enkoderami magnetycznymi na przedłużonym wale. Silnikami steruje poprzez dwa oddzielne mostki TB6612 i mikrokontroler STM32f103VCT6. Mój problem polega na tym, że zadając identyczną wartość sygnału PWM na oba mostki H zauważyłem, że koła nie kręcą się z jednakową prędkością tzn. jedno koło spóźnia się względem drugiego. O co chodzi ? Dodam, że regulacja prędkości kół jest dla mnie bardzo istotna, ponieważ w przypadku obrotu robota w miejscu z różnymi prędkościami kół robot przesunie się względem osi obrotu co dla mojego projektu jest dużym utrudnieniem, co obrazowo przedstawiłem na załączonym rysunku. Proszę o jakieś wskazówki i pomoc 🙂
  14. Cześć ! W artykule wzór na wyznaczenie wartości macierzy kowariancji Ppost jest następujący : Ppost = Ppri - K*S*K ale w literaturze przedmiotu wzór jest inny tzn. : Ppost = (I - K*C) * Ppri ;gdzie I jest macierzą jednostkową 2x2 i teraz mam pytanie do autora artykułu GandalF jak przekształcić wzór : Ppost = (I - KC)*Ppri do Ppost = Ppri - KSK? Proszę o pomoc w tej sprawie, bo próbowałem to przekształcić i cały czas mi się coś nie zgadza 😞
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.