Pavouk Hiwonder

Nedaří se vám s projektem a nenašli jste vhodné místo, kde se zeptat? Napište sem.
Pravidla fóra
Tohle subfórum je určeno pro konzultaci ucelených nápadů, popřípadě řešení komplexnějších projektů, které opravdu není možné rozdělit na menší části.
Většinu problémů jde rozdělit na menší a ptát se na ně v konkrétních subfórech.
Odpovědět
luger
Příspěvky: 163
Registrován: 30 dub 2023, 11:06
Reputation: 0

Re: Pavouk Hiwonder

Příspěvek od luger » 14 kvě 2024, 09:59

Výborně, díky, už je mi to jasnější. Potřebuji do té hromady podmínek vnořit podmínku na kontrolu gyroskopu aby když se pavouček moc nakloní tak se zastaví. Je to ochrana proti spadnutí z "vyvýšené překážky" nebo když ho chci přenést za chodu.
Prozatím jsem gyro kontrolu vrazil do smyčky loop, ale problém je v tom že knihovna na kráčení (LobotController) běží jakoby na pozadí a je ovládaná jen měřením vzdálenosti z ultrazvuku a funkcí millis. A v tom je zakopaný pes. Když dojde k přerušení díky gyro tak se rozhodí millis a timer a pavouček se zasekne.

Uživatelský avatar
Caster
Příspěvky: 398
Registrován: 11 zář 2019, 09:02
Reputation: 0

Re: Pavouk Hiwonder

Příspěvek od Caster » 14 kvě 2024, 13:00

Aplikaci, která současně vykonává více funkcí, které jsou časově kritické bych naprogramoval ve FreeRTOS ;) .

Arduino FreeRTOS Tutorial 1 - Creating a FreeRTOS task to Blink LED in Arduino Uno

luger
Příspěvky: 163
Registrován: 30 dub 2023, 11:06
Reputation: 0

Re: Pavouk Hiwonder

Příspěvek od luger » 14 kvě 2024, 14:44

Díky Caster, a je to bezpečné ? Nerad bych si ten stávající program nějak rozhodil. Neovlivní to nějak knihovny ? Jsem začátečník tak se raději zeptám než zahodím půl roku přemýšlení a testování

Uživatelský avatar
Caster
Příspěvky: 398
Registrován: 11 zář 2019, 09:02
Reputation: 0

Re: Pavouk Hiwonder

Příspěvek od Caster » 14 kvě 2024, 18:50

V pohodě. Bezpečné to je. Asi bych si nejdříve zkusil nějaký jednoduchý příklad, např. to blikání LED a pak projekt pavouka upravil na FreeRTOS postupným přidávání modulů a úloh (tásků), které se budou volat. Na začátku by bylo dobré si rozmyslet, kolik úloh budeš potřebovat, jaká bude mít každá úloha prioritu (např. výpis na displej může počkat, není tak důležitý) a jak dlouho bude každá trvat (v ms). Problém není ani případné předávání dat mezi jednotlivými úlohami většinou přes frontu (quee) a prioritní volání určité funkce při přerušení.

Naučit se to vše bude samozřejmě nějakou dobu trvat. Podívej se také na příklady FreeRTOS na youtube.

Pokud umíš anglicky, můžež jednotlivé problémy konzultovat v FreeRTOS Community Forums, případně přímo ve fóru pro Arduino viz např. Can't execute codes in loop() function under "Arduino UNO R3 + Arduino_FreeRTOS.h" multi-tasking environment.

Popis významu písmen před názvy funkcí.

FreeRTOS - použití a nástrahy časovačů

P.S. Já programuji ve FreeRTOS a C++ 32bitové mikroprocesory SAMD21/SAMR34

luger
Příspěvky: 163
Registrován: 30 dub 2023, 11:06
Reputation: 0

Re: Pavouk Hiwonder

Příspěvek od luger » 14 kvě 2024, 20:52

Díky, v rychlosti jsem se na to kouknul , ale myslím, že dokud nepochopím původní tovární program tak je blbost ho nějak radikálně překopávat.

Prozatím jsem vypracoval tuto tezi:

Pro návštěvníky tohoto vlákna, kterým se nechce pročítat minulé příspěvky:
Pavouček Hiwonder je polo-profi robot hexapod osazený Arduinem UNO, Servoshieldem, gyroskopem, PIR senzorem, ultrazvukovým senzorem, zvukovým a světelným čidlem. Pro zobrazování různých informací slouží oled displej. ESP32 CAM slouží k přenosu obrazu přes wifi na PC nebo mobil. Pro pohon jsou použité vysokonapěťové serva typu BUS se silou 20kg/cm.
Není to žádný drobek, když se rozčapí tak měří 70 cm a váží něco málo do 3 kg. Baterie je Li-ion 5500 mAh.

Pavouček by měl sloužit jako „domací mazel“ ale taky jako „hlídač“ .

První podmínka, kterou jsem si dal je, že musí být naprosto autonomní, žádný kabel, žádné dálkové ovládání. Pouze vyhodnocování vnějších podnětů. Netušil jsem co mě čeká.

Takže co by měl umět a čeho chci docílit:

- kráčení vpřed, vzad, přesun do stran a otáčení vlevo/vpravo na místě různou rychlostí. Tato rychlost závisí na volném prostoru a vzdálenosti případné překážky. K blízké překážce se plazí a kontroluje. Když je všude volno tak běží na max, ale stále kontroluje. Různé způsoby kráčení je jednoduché naprogramovat.
Vzhledem k rozměrům pavoučka nestačí měřit jen vzdálenost „přímo před sebou“ ale také mírně do stran aby se zamezilo kontaktu kráčejících nožiček o případnou překážku, která je mimo měřený úhel senzoru. Proto jsem naprogramoval neustálé kmitání serva se senzorem v úhlech +20°,0,-20° k pokrytí většího prostoru. Následující přepočet všech tří změřených vzdáleností určí průběh další činnosti.

- neustálá kontrola hodnot ze senzorů :
- gyroskop – kontrola náklonu. V případě velkého náklonu zastavit kráčení
- světlo – při slabém světle se zapne osvětlovací dioda pro lepší obraz z kamery
- zvuk – při zvukovém signálu (písknutí, tlesknutí) – udělej určitou operaci – zatím ještě nevím jakou

- po určité době proveď – zastav, lehni , vypni osvětlení a čekej
- čeká se na zvukový nebo světelný (světlo/tma) signál a PIR – vyhodnocení signálu a následuje další činnost
- za nějakou dobu, když se nic neděje, tak se přemísti na jinou pozici a zase lehni a čekej

- zobrazování informací na oled – přehled údajů ze senzorů a počty kroků
- zobrazení náklonu – X,Y,Z ve stupních
- počet provedených kroků
- analog hodnoty světelného a zvukového senzoru
- aktivace PIR

- přenos obrazu z ESP32 CAM modulu na mobil nebo PC

- hudba budoucosti – ukládej všechny hodnoty z pohybů a senzorů, vyhodnocuj je, ukládej a výsledek pak použij k další činnosti (taková malá AI) – zatím vůbec nemám představu jak by to mohlo fungovat

Celkem mi to funguje ale některé akce ještě musím vyladit.

luger
Příspěvky: 163
Registrován: 30 dub 2023, 11:06
Reputation: 0

Re: Pavouk Hiwonder

Příspěvek od luger » 18 kvě 2024, 11:59

Chtěl bych tímto požádat kolegy gilhat a kiRRow o vyjádření k posloupnosti podmínek které ovládají pavoučka. Myslím že vy tomu fakt rozumíte a snad mi pomůžete. Především se mi jedná o "vkládání dalších podmínek (např. ze senzoru)" do tohoto guláše podmínek a přitom si nerozhodil funkci millis., vlastně ani nevím proč tam ta funkce kontroly millis je.
Nejhorší na tom je že vůbec nechápu jak funguje knihovna Lobot Controller a příslušný program Lobot.cpp :( takže nevím co s tím.

Kód: Vybrat vše

// Hlavní posloupnost kroků ovládání pavoučka v závislosti na změřené vzdálenosti překážky ultrazvukem a
// na kontrole náklonu přes gyroskop (zastavit kráčení). 


void sonar ();
  
  static uint32_t timer = 0;    //počáteční hodnota pro časovač
  static uint8_t  step_ = 0;    //počáteční hodnota pro kroky    step_
           
  if (timer > millis())        //Vraťte se,pokud je nastavený čas větší než aktuální počet milisekund,pokud ne,
                               //pokračujte v následujících operacích.
    return;
    switch (step_)               //skákání na funkce "case" podle  step_
  {
//-----------------------------------------------------------------------------------------------------------------    
    case 0:                                

      zmerit_vzdalenost();                //změřit vzdálenost ultrazvukem vpředu a uložit do  vzdalenost - kmitání

      if (!Controller.isRunning()) {            //Pokračuj, dokud nebude ukončena akční skupina pohybu, knihovna Lobot

          if (vzdalenost > 160 ){ 
          Controller.runActionGroup(RYCHLE, 0);    // rychlé kráčení vpřed, 0- znamená neustále do přerušení
          step_ = 1;                                   
        }
      
        else if (vzdalenost >= 100 ){ 
          Controller.runActionGroup(POMALU, 0);    //kráčet rychle (nebo pomalu) vpřed    0- znamená neustále až do přerušení , RYCHLE
          step_ = 1;                                   //skočit na step 1
        }
        
        else if (vzdalenost >= 50 ) {
             Controller.runActionGroup(TEREN_POMALU, 0);    //kráčet  pomalu  vpřed    0- znamená neustále až do přerušení ,  "POMALU"
             step_ = 1;                                   //skočit na step 1
            }
            
        else if (vzdalenost >= 38 || vzdalenost == 0) {       
            Controller.runActionGroup(PLAZENI, 0);       //kráčet  nejpomaleji vpřed    0- znamená neustále až do přerušení
            step_ = 1;                                   //skočit na step 1
        } 
                
        else {                             
          Controller.stopActionGroup();   // zastavit kráčení
          step_ = 2;                      // skočit na  step 2
          timer = millis() + 500;         // zjišťuje stav každých 500 ms (původní tovární hodnota 500)
        }
      }
       break;                             // ukončení podmínky pro přepínání
      
//---------------------------------------------------------------------------------------------------------      
    case 1:                               // step 1
       test_naklonu ();                   //kontrola náklonu pomocí gyroskopu
       zmerit_vzdalenost ();              // podprogram ke změření vzdálenosti ultrazvukem vpředu
       
       if ((vzdalenost <= 38 && vzdalenost > 0) or (pocet_naklonu == 1)) {
                                  // Pokud je naměřená vzdálenost menší než specifikovaná vzdálenost pro vyhnutí se překážce (380 mm) 
                                  // nebo náklon z gyro pak zastavte všechny akční skupiny a přejděte ke kroku 2.
                                  
        Controller.stopActionGroup();       // zastavit
        sonarServo.stop ();                 // zastavení serva ultrazvuku
        step_ = 2;                          // skočit na step 2
        timer = millis() + 500;             // původní hodnota 500 
      }
      break;                                // ukončení kroku 1
      
//------------------------------------------------------------------------  kontrola VLEVO a VPRAVO  -----------------------------------      
    case 2:

      if (!Controller.isRunning()) {      // pokud stojí tak změř vzdálenosti vlevo a vpravo, jinak běž na step 3
        getAllDistance();                 // změřit vzdálenost ve všech třech směrech
        step_ = 3;                        // skočit na case 3
      } 
      else {
        timer = millis() + 500;           // původní hodnota 500 
      }
      break;                              // ukončení kroku 2
      
//----------------------------------------------------------------------------------------------------------------      
    case 3:
      static bool lastActionIsGoBack = false;        //Statická proměnná - zaznamenat, zda je poslední akce zpět
                                                
     if (((vzdalenost_vpred > 38) || (vzdalenost_vpred == 0)) && lastActionIsGoBack == false) {
        
        //Pokud je mezilehlá vzdálenost větší než zadaná vzdálenost pro vyhnutí se překážce (cca 380 mm) a poslední akcí není ustoupit,
        //vraťte se ke kroku 0. Posuzuje se, zda se poslední akce vrací zpět nebo ne, aby se zabránilo pádu programu do
        //smyčky zpět-"dopředu-"dozadu-"dopředu..."
        //      Když je poslední krok zpět, neprovede se vpřed

        step_ = 0;                     // návrat na krok 0 
        timer = millis() + 200;        // původní hodnota 200
        lastActionIsGoBack = false;
        break;
      }
      
      if ((((vzdalenost_vlevo >= vzdalenost_vpravo) && (vzdalenost_vlevo >= 38)) || vzdalenost_vlevo == 0) && vzdalenost_vpred > 20) {
        
        //Když je vzdálenost na levé straně měřená ultrazvukem větší než vzdálenost na pravé straně
        //větší než specifikovaná vzdálenost pro vyhnutí se překážce a vzdálenost naměřená uprostřed je větší než 200 mm
        //Účelem detekce vzdálenosti uprostřed je vyhnout se předmětům mezi dvěma předními nohami robota, které způsobí
        // že se robot nemůže otočit.
        
        if (!Controller.isRunning()) {                              //Počkejte, dokud nebude ukončena aktivní skupina, příkaz knihovny Lobot
          
          if (vzdalenost_vlevo > 80){                              // když je vzdálenost vlevo větší než 1000 tak boční přesun
            Controller.runActionGroup(PRESUN_DOLEVA_POMALU, 3);    // 3x přesunout doleva 
            goto presunL;                                 // přesunout se bokem doleva a pokračovat bez otáčení                                 
          }
          
          Controller.runActionGroup(DOLEVA, 4);           // 4x zatočit doleva nízký postoj, příkaz knihovny Lobot
          
          presunL:
          
          lastActionIsGoBack = false;               // Identifies that the last action is not back, kontrola kroku zpět
          step_ = 0;                                // zpět na krok 0 
          timer = millis() + 300;                   // původně 300
        }        
      }
      
      else if ((((vzdalenost_vpravo > vzdalenost_vlevo) && (vzdalenost_vpravo > 38)) || vzdalenost_vpravo == 0) && vzdalenost_vpred > 20) {
        // Když je minimální vzdálenost na pravé straně měřená ultrazvukem větší než minimální vzdálenost na levé straně
        // větší než specifikovaná vzdálenost pro vyhnutí se překážce a vzdálenost měřená uprostřed (mezi nohama)
        //je větší než 200 mm
        
        if (!Controller.isRunning()) {                //Počkat, dokud nebude ukončena akční skupina
          
          if (vzdalenost_vpravo > 80){                         // když je vzdálenost vpravo větší než 1000 tak boční přesun
            Controller.runActionGroup(PRESUN_DOPRAVA_POMALU, 3);
            
            goto presunR;                                 // přesunout se bokem doprava a pokračovat bez otáčení                                 
          }
          
          Controller.runActionGroup(DOPRAVA, 4);        // 4x zatočit na místě doprava
          
          presunR:
                    
          lastActionIsGoBack = false;         //Identifies that the last action is not back
          step_ = 0;                          // zpět na krok 0
          timer = millis() + 300;             // původně 300
        }           
      }
      
      else {
        Controller.runActionGroup(GO_BACK, 4);      // 4x kráčet zpět 
                
        lastActionIsGoBack = true;                   //poslední akce kráčení je zpět
        step_ = 2;                                   //skok  step 2
        timer = millis() + 300;                      // původně 300
      }
      break;
  }
}

void loop ()
sonar

Uživatelský avatar
kiRRow
Příspěvky: 1193
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Pavouk Hiwonder

Příspěvek od kiRRow » 18 kvě 2024, 14:46

Tak vždy se provede buď žádný, nebo vždy pouze jediný case ...
při case 0 se testuje ten Controller.isRunning ,pokud ano tak se testuje vzdálenost a spustí se vždy a jen pouze první platná podmínka, tzn pokud bude vzdálenost >= 130, tak se spustí ten else if (vzdalenost >= 100 ) a ten za ním už se testovat nebude rovnou to skočí na break; který vyskočí z toho switche ven. Pokud nedopadne dobře ani jedno z těch else if, tak se provede else.
case 1 tam je jen jedna rozhodovací if podmínka, buď se splní nebo ne
case 2 skoro to samé, akorát podmínka je buď a nebo, jedna část se vždy splní
case 3 tam máš dvě podmínky
nejprve se otestuje tahle if (((vzdalenost_vpred > 38) || (vzdalenost_vpred == 0)) && lastActionIsGoBack == false) {
a po ní se otestuje if ((((vzdalenost_vlevo >= vzdalenost_vpravo) && (vzdalenost_vlevo >= 38)) || vzdalenost_vlevo == 0) && vzdalenost_vpred > 20) { a ta buď splní 1případ, pak už nebude testovat ten else if, a nebude ani dělat else ... a pokud se ji nepovede 1případ, zkusí to else if, a pokud ani to ne ... tak provede to co je za else

luger
Příspěvky: 163
Registrován: 30 dub 2023, 11:06
Reputation: 0

Re: Pavouk Hiwonder

Příspěvek od luger » 18 kvě 2024, 15:15

díky kiRRow, ty podmínky jsou mi docela jasné, ale myslím že je problém v tom časování - millis. Proč je někde 500, jinde 300 a jinde 200 ? Ono totiž když tam (někam) vrazím další podmínku, třeba to čtení gyroskopu nebo nějakého senzoru tak se celý průběh zasekne a pavouček si dělá co chce. Jakoby se vracel k podmínkám které by už měl mít zkontrolované a kontroluje je znova. Např. změří vzdálenost, zjistí že je 120 a tak běží POMALU, ale po chvíli se zastaví a opět změří vzdálnost , změní rychlost anebo se otočí apod. Prostě nepřídvídatelné pohyby. Myslím že to způsobuje právě ta funkce millis, ale nechápu proč. Jinak nevím na co tam je.

Uživatelský avatar
kiRRow
Příspěvky: 1193
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

Re: Pavouk Hiwonder

Příspěvek od kiRRow » 18 kvě 2024, 15:24

no tím nastavuješ jak často vůbec chceš ten hlavní switch spouštět, on spíš problém bude dělat to, že millis používá přerušení - jakmile nějaká knihovna, nebo nějaká funkce ty přerušení zakážou, nebo používají taky, tak se to právě tak nějak začne chovat podivně bez zjevného důvodu ...

luger
Příspěvky: 163
Registrován: 30 dub 2023, 11:06
Reputation: 0

Re: Pavouk Hiwonder

Příspěvek od luger » 18 kvě 2024, 15:51

Posílám video kde je krásně vidět "sekání pohybů" a vyhodnocování:
https://www.youtube.com/watch?v=YONvP9dCtZ4

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 2 hosti