- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 10 von 41

Thema: RP6 Linienfolger

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Echt krass was die Lampe bringt. Das Programm ist immer noch minimal, aber das Ergebniss ist trotzdem prima:

    Bild hier  
    http://www.youtube.com/watch?v=r2VC2YF7ycM

    Code:
    // Einfaches Linienfolgen mit RP6-Sensoren (Test der Funktion 2)     6.3.2008 mic
    
    #include "RP6RobotBaseLib.h"
    
    // Achtung! Die PWM-Werte werden hier OHNE Rampe verändert!
    void setMotorPWM(uint8_t power_links, uint8_t power_rechts)
    {
    extern uint8_t mleft_ptmp, mright_ptmp;
    
    	if(power_links > 210) power_links = 210;
    	if(power_rechts > 210) power_rechts = 210;
    	mleft_power=mleft_ptmp=power_links;
    	mright_power=mright_ptmp=power_rechts;
    
    	OCR1BL = power_links;
    	OCR1AL = power_rechts;
    
    	if(power_links || power_rechts)
    		TCCR1A = (1 << WGM11) | (1 << COM1A1) | (1 << COM1B1);
    	else
    		TCCR1A = 0;
    }
    int main(void)
    {
    	initRobotBase();
    	while(1)
    	{
    		writeInteger(readADC(ADC_LS_L), 10);
    		writeString_P(" - ");
    		writeInteger(readADC(ADC_LS_R), 10);
    		writeString_P("\n\r");
    		if (readADC(ADC_LS_L) > readADC(ADC_LS_R))
    		{
    		   setLEDs(4);
    			setMotorPWM(100,50);
    		}
    		else
    		{
    			setLEDs(32);
    		   setMotorPWM(50,100);
    		}
    		mSleep(100);
    	}
    	return(0);
    }
    Der "Reflektor" ist ein Blatt Papier, die Werte auf den Fliesen sind über 800!

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    26.10.2013
    Beiträge
    8
    Zitat Zitat von radbruch Beitrag anzeigen
    Hallo

    Echt krass was die Lampe bringt. Das Programm ist immer noch minimal, aber das Ergebniss ist trotzdem prima:

    Bild hier  
    http://www.youtube.com/watch?v=r2VC2YF7ycM

    Code:
    // Einfaches Linienfolgen mit RP6-Sensoren (Test der Funktion 2)     6.3.2008 mic
    
    #include "RP6RobotBaseLib.h"
    
    // Achtung! Die PWM-Werte werden hier OHNE Rampe verändert!
    void setMotorPWM(uint8_t power_links, uint8_t power_rechts)
    {
    extern uint8_t mleft_ptmp, mright_ptmp;
    
    	if(power_links > 210) power_links = 210;
    	if(power_rechts > 210) power_rechts = 210;
    	mleft_power=mleft_ptmp=power_links;
    	mright_power=mright_ptmp=power_rechts;
    
    	OCR1BL = power_links;
    	OCR1AL = power_rechts;
    
    	if(power_links || power_rechts)
    		TCCR1A = (1 << WGM11) | (1 << COM1A1) | (1 << COM1B1);
    	else
    		TCCR1A = 0;
    }
    int main(void)
    {
    	initRobotBase();
    	while(1)
    	{
    		writeInteger(readADC(ADC_LS_L), 10);
    		writeString_P(" - ");
    		writeInteger(readADC(ADC_LS_R), 10);
    		writeString_P("\n\r");
    		if (readADC(ADC_LS_L) > readADC(ADC_LS_R))
    		{
    		   setLEDs(4);
    			setMotorPWM(100,50);
    		}
    		else
    		{
    			setLEDs(32);
    		   setMotorPWM(50,100);
    		}
    		mSleep(100);
    	}
    	return(0);
    }
    Der "Reflektor" ist ein Blatt Papier, die Werte auf den Fliesen sind über 800!

    Gruß

    mic


    Wie kann ich hier veranlassen das der Robby rückwärts statt vorwärts fährt?

  3. #3
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Die Drehrichtungen der Antriebe kann man mit setMotorDir() aus der Library RP6RobotBaseLib.c festlegen:

    Code:
    /**
     * Sets the rotation direction of both motors.
     *
     * DO NOT CHANGE THE DIRECTION OF THE MOTORS WHILE THEY
     * ARE RUNNING AT HIGH SPEEDS!!! 
     * It will not instantly damage the motors/gears, but they will  
     * wear out much faster if you do it at high speeds - better wait 
     * until speed has slowed down - and change direction AFTER this.
     *
     * -------------------------------------------------------------
     * IT IS A BETTER IDEA NOT TO USE THIS FUNCTION AT ALL!
     * Use moveAtSpeed together with task_motionControl instead.
     * YOU CAN NOT USE setMotorPower AND setMotorDir WHEN YOU USE 
     * task_motionControl!  This will not work!
     * -------------------------------------------------------------
     *
     * task_motionControl also ensures that the direction is changed
     * slowly and only after the motors have stopped!
     *
     * Example:
     *          // DO NOT perform these commands directly after each
     *			// other in your programs - this is just a LIST of possible
     *			// combinations:
     *			setMotorDir(FWD,FWD); // Move forwards
     *			setMotorDir(BWD,FWD); // Rotate right
     *			setMotorDir(FWD,BWD); // Rotate left
     *			setMotorDir(BWD,BWD); // Move backwards
     *
     */
    void setMotorDir(uint8_t left_dir, uint8_t right_dir)
    {
    	mleft_dir = left_dir;
    	mright_dir = right_dir;
    	mleft_des_dir = left_dir;
    	mright_des_dir = right_dir;
    	if(left_dir)
    		PORTC |= DIR_L;
    	else
    		PORTC &= ~DIR_L;
    	if(right_dir)
    		PORTC |= DIR_R;
    	else
    		PORTC &= ~DIR_R;
    }
    Wie beschrieben sollten die Drehrichtungen nicht bei Vollgas umgeschaltet werden!

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    26.10.2013
    Beiträge
    8
    könntest du mir anhand dem Programm welches ich gesendet habe, aufzeigen? lg

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    06.11.2010
    Beiträge
    773
    Hi EK9,

    sorry, aber da wirst du selber ran müssen. In dem Forum wird keiner für dich den Code umschreiben
    Schau mal in die Anleitung und in die Beispielprogramme. Dort findest du viele Beispiele und Erklärungen zu den ganzen Funktionen, auch zu setMotorDir() usw.

    Ist gar nicht so schwer, und durch ausprobieren lernst du mehr als durch ablesen.
    Wenns dann scheitert, hilft dir hier sicherlich jeder herauszufinden, warum!

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    26.10.2013
    Beiträge
    8
    Guten Abend, kann mir jemand diese einzelnen Instruktionen erklären, was diese heissen?



    void setMotorPWM(uint8_t power_links, uint8_t power_rechts)
    {
    extern uint8_t mleft_ptmp, mright_ptmp;

    if(power_links > 210) power_links = 210;
    if(power_rechts > 210) power_rechts = 210;
    mleft_power=mleft_ptmp=power_links;
    mright_power=mright_ptmp=power_rechts;

    OCR1BL = power_links;
    OCR1AL = power_rechts;

    if(power_links || power_rechts)
    TCCR1A = (1 << WGM11) | (1 << COM1A1) | (1 << COM1B1);
    else
    TCCR1A = 0;

  7. #7
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Es ist mir völlig unklar, warum du dich bei der umfangreichen RP6-Library ausgerechnet auf diese Funktion stürzt anstatt die Library anhand ihrer einzelnen Demoprogramme zu erkunden. Der RP6 ist so komplex, da wirst du nicht weit kommen, wenn du nicht etwas Eigeninitiative entwickelst.

    Kurz zur Funktion setMotorPWM(). Sie dient dazu die PWM-Werte für die Antriebe direkt zu setzen und die entsprechenden Variablen der Library anzupassen:

    Die erste Hälfte stellt den Bezug zu den in der Library verwendeten Variablen her, begrenzt die PWM-Werte auf den in der Lib verwendeten und in dieser Timerbetriebsart durch das ICRA-Register gesetzten Maximalwert von 210 und lädt schließlich die Libraryvariablen mit den geänderten Werten. Im zweiten Teil der Funktion werden die Compare-Register der beiden Seiten mit dem PWM-Wert geladen und der Timer aktiviert, wenn die PWM-Werte dies erfordern.

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  8. #8
    Erfahrener Benutzer Roboter-Spezialist Avatar von RolfD
    Registriert seit
    07.02.2011
    Beiträge
    414
    Anmerkung... hat sich mit Radbruchs Post überschnitten...

    Eigentlich recht wenig. Von unten hoch... stell dir vor, irgendwo im RP6 (Prozessor) gibts einen Taktgenerator den man VOReinstellen kann... das passiert indem auf das Register TCCR1A geschrieben wird. Damit der Zähler weis wie weit er zählen soll, beschreibt man die Register OCR1BL und OCR1AL wobei das Einfluß auf die Energiemenge der Motoren hat. 0 heisst Motor hat kein Strom bzw. 0%, 210 ist Vollgas und 100%... bei 2 Ketten bzw. 2 Motoren (OCR1BL=links und OCR1AL=rechts) kann man also je Kette getrennt die angelegte Leistung kontrollieren. Da der Wert von 210 nicht überschritten werden sollte ( hängt u.a. mit dem Teilerfaktor zusammen ), werden die Werte zwischengespeichert und geprüft bzw. auf max=210 gesetzt.

    Jetzt von oben nach unten...
    Die Funktion bekommt die Speed für beide Motoren übergeben, prüft diese auf positive 210 max und setzt sie ggf. runter, zwischenspeichert das in eine externe Variable, schreibt beide Werte in die jeweiligen PWM Zählerregister OCR1xx und setzt PWM Modus, Vorteiler usw.

    Die Funktion ist also quasi das Gaspedal für den RP6.
    Würde man dort z.B. auch die Richtung setzen wollen.. was nicht mal so dumm wäre... würde man schreiben:
    Code:
    void setMotorPWM_spezial(uint8_t power_links, uint8_t power_rechts, uint8_t left_dir, uint8_t right_dir)
    {
    extern uint8_t mleft_ptmp, mright_ptmp;
    
    if(power_links > 210) power_links = 210;
    if(power_rechts > 210) power_rechts = 210;
    mleft_power=mleft_ptmp=power_links;
    mright_power=mright_ptmp=power_rechts;
    mleft_dir = left_dir;
    mright_dir = right_dir;
    mleft_des_dir = left_dir;
    mright_des_dir = right_dir;
    
    OCR1BL = power_links;
    OCR1AL = power_rechts;
    if(left_dir)
        PORTC |= DIR_L;
    else
        PORTC &= ~DIR_L;
    if(right_dir)
        PORTC |= DIR_R;
    else
        PORTC &= ~DIR_R;
    
    if(power_links || power_rechts)
    TCCR1A = (1 << WGM11) | (1 << COM1A1) | (1 << COM1B1);
    else
    TCCR1A = 0;
    }
    


    dann noch den Prototypen bauen... nen "extern" muss da glaub ich auch noch rein.. damit c nicht meckert.. und schon hast du eine Funktion die nicht nur Geschwindigkeit sondern auch die Richtung verarbeitet. Bei der Richtungsverarbeitung wird einfach nur festgelegt, an welchen der 4 möglichen Pins die Signale abgegeben werden soll wobei nur 2 aktiv sein dürfen. Nachteil ist, das man nun auch ständig die Richtung mitgeben muss und sie sollte sich nicht spontan ändern wenn das Getriebe läuft. Schaut man sich die anderen Motorfunktionen an (was ich Dir empfohlen hatte!!!), stellt man aber fest, das es sowas schon in der RP6lib gibt.
    Da steht auch sehr deutlich:
    IT IS A BETTER IDEA NOT TO USE THIS FUNCTION AT ALL!
    Man kann das ganze noch aufhübschen.. in dem man z.B. auf echte % umrechnet, negative Werte als rückwärts verarbeitet und damit die 2 extra Parameter spart... aber "zweckmäßig" reicht meist auch vollkommen und ist meist kürzer im Speicher.
    Nun solltest du dich aber mal mit der Theorie und Praxis von PWM beschäftigen... dazu finden sich schöne Artikel im Wiki ebenso wie in der Docu vom Prozessor.
    Gruß Rolf
    Geändert von RolfD (18.11.2013 um 21:45 Uhr)
    Sind Sie auch ambivalent?

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests