Hi inka,
was hast du vor?
Mit changeDirection(dir) kann man ja mit dem Parameter dir in alle Richtungen (FWD, BWD, LEFT, RIGHT) steuern.
Klappt das damit nicht?
Hi inka,
was hast du vor?
Mit changeDirection(dir) kann man ja mit dem Parameter dir in alle Richtungen (FWD, BWD, LEFT, RIGHT) steuern.
Klappt das damit nicht?
Gruß
Dirk
Hi Dirk,
was ich vorhabe? Den versuch den code aus meinem ersten post für den RP6 "auferstehen" zu lassen. Die ganzen berechnungen so zu lassen, wie sie sind und die asuro-funktionen durch ihre RP6 äquivalente zu ersetzten und schauen, was der RP6 damit tut...
dabei ist noch die funktion
aus der asuro-lib motor_low.c geblieben, die - so wie ich sie verstehe - die drehrichtung der beiden motoren unabhängig voneinander und auch noch in der größe unterschiedlich, abhängig von der variablen verändert. Meine frage war, ob ich das so richtig sehe und wie ich das nachbilden kann.Code:inline void MotorDir ( unsigned char left_dir, unsigned char right_dir) { PORTD = (PORTD &~ ((1 << PD4) | (1 << PD5))) | left_dir; PORTB = (PORTB &~ ((1 << PB4) | (1 << PB5))) | right_dir; }
hier noch die motor_low.c zum verständnis:
Code:/****************************************************************************/ /*! \file motor_low.c \brief Low Level Funktionen zur Steuerung der Motoren. Die Motorsteuerung erfolgt grundsaetzlich ueber die auf der Asuro-Platine\n aufgebauten H-Bruecken. Dies ist eine Schaltung, ueber die ein Strom in\n verschiedene Richtungen durch die Motoren geleitet werden kann.\n Zur Geschwindigkeitssteuerung werden die beiden im Prozessor vorhandenen\n PWM-Kanaele genutzt, deren Ausgangssignale die Staerke des Stromflusses in\n den H-Bruecken beinflusst.\n Die Initialisierung der PWM-Funktionalitaet erfolgt in der Funktion Init(). \see Defines fuer die Auswahl der ADC-Kanaele in asuro.h\n FWD, RWD, BREAK, FREE \version V--- - 10.11.2003 - Jan Grewe - DLR\n Original Version von der ASURO CD\n \version V--- - bis zum 07.01.2007 - \n Bitte in Datei CHANGELOG nachsehen.\n \version V001 - 13.01.2007 - m.a.r.v.i.n\n +++ Alle Funktionen\n Zerlegte Sourcen in einzelne Dateien fuer eine echte Library. \version V002 - 05.02.2007 - Sternthaler\n +++ Alle Funktionen\n Kommentierte Version (KEINE Funktionsaenderung) \version V003 - 18.02.2007 - m.a.r.v.i.n\n Datei gesplitted in motor_low.c und motor.c *****************************************************************************/ /***************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * any later version. * * * *****************************************************************************/ #include "asuro.h" /****************************************************************************/ /*! \brief Steuert die Geschwindigkeit der Motoren. \param[in] left_speed Geschwindigkeit linker Motor (Bereich 0..255) \param[in] right_speed Geschwindigkeit rechter Motor (Bereich 0..255) \return nichts \see Die Initialisierung der PWM-Funktionalitaet erfolgt in der Funktion Init(). \par Hinweis: Diese Funktion ist als 'inline'-Funktion definiert. \par Arbeitsweise: Ueber die Parameter werden die beiden Kanaele der PWM-Funktionalitaet im\n Prozessor angesteuert. Diese Art der Geschwindigkeitsreglung beruht darauf,\n dass ein digitaler Output-Pin in schneller Folge an- und ausgeschaltet wird.\n Mit dem Parameter wird nun gesteuert wie \b lange der Strom im \b Verhaeltniss \n zur Zykluszeit \b angeschaltet ist.\n Wird z.B. ein Wert von 150 fuer einen Parameter uebergeben, dann wird fuer\n 150 / 255-tel der Zykluszeit der Port auf 1 geschaltet und somit ist die\n Motorleistung entsprechend reduziert.\n Daraus ergibt sich auch dass der Asuro \b noch \b nicht bei einem Wert von\n 20 fahren wird, da diese Leistung nicht ausreicht ihn 'anzuschieben'.\n (PWM = Pulsweitenmodulation) \par Beispiel: (Nur zur Demonstration der Parameter/Returnwerte) \code // Setzt die Geschwindigkeit fuer den linken Motor // auf 150 und stoppt den rechten Motor. MotorSpeed (150, 0); \endcode *****************************************************************************/ inline void MotorSpeed ( unsigned char left_speed, unsigned char right_speed) { OCR1A = left_speed; OCR1B = right_speed; } /****************************************************************************/ /*! \brief Steuert die Drehrichtung der Motoren. \param[in] left_dir Richtung des linken Motors [ FWD | RWD | BREAK | FREE ] \param[in] right_dir Richtung des rechten Motors [ FWD | RWD | BREAK | FREE ] \return nichts \par Hinweis: Diese Funktion ist als 'inline'-Funktion definiert. \par Arbeitsweise: Ueber die Parameter werden die Port-Pin's zu den H-Bruecken beider Motoren so\n gesetzt, dass die jeweils 4 beteiligten Transitoren einer Bruecke den Strom\n durch die Motoren entweder - FWD vorwaerts durchleiten - RWD rueckwaerts durchleiten - BREAK den Motor kurzschliessen (Bremswirkung) - FREE oder von der Stromversorgung trennen (Motor laeuft aus) \par Beispiel: (Nur zur Demonstration der Parameter/Returnwerte) \code // Setze die Richtung fuer den rechten Motor auf Rueckwaerts // und blockiert den linken Motor. MotorDir (BREAK, RWD); \endcode *****************************************************************************/ inline void MotorDir ( unsigned char left_dir, unsigned char right_dir) { PORTD = (PORTD &~ ((1 << PD4) | (1 << PD5))) | left_dir; PORTB = (PORTB &~ ((1 << PB4) | (1 << PB5))) | right_dir; }
gruß inka
Hi inka,
das Problem ist nicht, dass es das nicht gibt (in der RP6RobotBaseLib):
setMotorPower(uint8_t left_power, uint8_t right_power)
setMotorDir(uint8_t left_dir, uint8_t right_dir)
Das Problem ist, dass der I2C-Slave diese Funktionen so nicht kennt.
Aber: Du hast ja auch schon die direkte IR-Empfänger-Abfrage in den Slave aufgenommen,- warum nicht auch diese 2 kleinen neuen Funktionen?
Gruß
Dirk
Hi Dirk,
ich bin keineswegs sicher, aber für die setMotorDir funktion würde ich folgendes ändern:
in der RP6Control_I2CMasterLib.c einfügen:
in der RP6Control_I2CMasterLib.h einfügen:Code:// Direction uint8_t left_dir; uint8_t right_dir; ------------------------------- /** * Set Motor dir function */ { setMotorDir(uint8_t left_dir, uint8_t right_dir) I2CTWI_transmit4Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_MOTOR_DIR, left_dir, right_dir ); while(I2CTWI_isBusy() || TWI_operation != I2CTWI_NO_OPERATION) task_I2CTWI(); }
in der RP6Base_I2CSlave.c einfügen:Code:#define CMD_SET_MOTOR_DIR 13 ------------------------------------------- void setMotorDir(uint8_t left_dir, uint8_t right_dir); -------------------------------------------- // Direction extern uint8_t left_dir; extern uint8_t right_dir;
Code:#define CMD_SET_MOTOR_DIR 13 ------------------------------------- in der Funktion "void task_commandProcessor(void)" einfügen: case CMD_SET_MOTOR_DIR: setMotorDir(param1, param2); break;
gruß inka
Ja, sieht doch gut aus.
Kleine Änderung in der "Set Motor dir function":
P.S.: Vorsicht mit den Funktionen, die die Motorrichtung und/oder Speed direkt schalten: Man kann (z.B. wenn man bei voll Speed vorwärts auf voll Speed rückwärts umschaltet) den RP6 evtl. schrotten!Code:/** * Set Motor dir function */ void setMotorDir(uint8_t left_dir, uint8_t right_dir) { I2CTWI_transmit4Bytes(I2C_RP6_BASE_ADR, 0, CMD_SET_MOTOR_DIR, left_dir, right_dir); while(I2CTWI_isBusy() || TWI_operation != I2CTWI_NO_OPERATION) task_I2CTWI(); }
Gruß
Dirk
Hi Dirk,
ok, danke, das void habe ich übersehen, mich wunderts sowieso, dass da so weing falsch war. Also mache ich mich an die zweite funktion...
wie ist das zu vermeiden? Oder ist das so, dass das risiko nur mit steigender speed auch steigt?
Eine andere idee: solche änderungen am funktionsumfang der I2C_slave (und zusammenhängende änderungen an der RP6Control_I2CMasterLib) wie die IR geschichte, oder jetzt die motorsachen, wäre es nicht sinnvoll das irgendwo "offiziell", also z.b. im Wiki für die allgemeinheit zu sammeln? Ich wüsste selber nicht, ob ich heute noch alle infos zu der IR sache finden würde, müsste schon mehr suchen, als wenn es irgendwo zusammengefasst wäre...
gruß inka
Hi inka,
In der Original-RP6-Lib wird die Speed nur mit "Rampen" verändert und z.B. bei Richtungswechsel erst die Speed reduziert, dann die Richtung geändert und wieder in die andere Richtung beschleunigt.wie ist das zu vermeiden? Oder ist das so, dass das risiko nur mit steigender speed auch steigt?
Wenn man ohne diese "Sicherheitsfunktionen" arbeiten will, dann muss man sich eigene Kontroll-Regeln einbauen.
Z.B.: Schalte die Drehrichtung eines Motors nur um, wenn die Speed des Motors < 40 ist. Wenn der Unterschied zwischen neuer (gewünschter) Speed und aktueller Speed > 30 ist, dann begrenze die neue Speed auf (aktuelle Speed + 30). Usw.
Ja, da wäre ich sehr dafür!solche änderungen am funktionsumfang der I2C_slave (und zusammenhängende änderungen an der RP6Control_I2CMasterLib) wie die IR geschichte, oder jetzt die motorsachen, wäre es nicht sinnvoll das irgendwo "offiziell", also z.b. im Wiki für die allgemeinheit zu sammeln? Ich wüsste selber nicht, ob ich heute noch alle infos zu der IR sache finden würde, müsste schon mehr suchen, als wenn es irgendwo zusammengefasst wäre...
Meine (bescheidene) Vorstellung:
Dein aktuelles Linienfolge-Programm gehört ja eigentlich zu deinem großen Projekt "RP6 sucht autonom eine induktive Ladestation auf".
Ich fände es absolut klasse, wenn das ganze Projekt zu einem eigenen Wiki-Artikel würde. Du hast dich da mit so viel Energie den Hardware- und Software-Fragen gestellt, dass das ein "Lehrstück" für Viele sein könnte (das Interesse zeigt sich ja z.B. durch die große Zahl der Aufrufe deiner Themen!).
Gruß
Dirk
Hi Dirk,
bist Du sicher, dass es sinnvoll ist anstelle der asuro-funktion:
die RP6-funktion:Code:inline void MotorSpeed ( unsigned char left_speed, unsigned char right_speed) { OCR1A = left_speed; OCR1B = right_speed; }
zu verwenden, statt das "moveAtSpeed()" direkt (und sichrere) zu verwenden?Code:void setMotorPower(uint8_t left_power, uint8_t right_power) { if(left_power > 210) left_power = 210; if(right_power > 210) right_power = 210; mright_power = right_power; mleft_power = left_power; }
das wird ja in der "RP6RobotBaseLib" sogar vorgeschlagen:
-------------------------------------------------------------
* 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!
* -------------------------------------------------------------
oder geht es aus irgendwelchen anderen gründen nicht?
gruß inka
Hi inka,
Die RP6-Lib Funktionen sind auf jeden Fall sicherer.bist Du sicher, dass es sinnvoll ist anstelle der asuro-funktion:
...
die RP6-funktion:
...
zu verwenden, statt das "moveAtSpeed()" direkt (und sichrere) zu verwenden?
Leider haben sie den Nachteil beim Linienfolgen, dass die Reaktion auf Änderungen der Richtung oder Geschwindigkeit etwas verzögert kommt.
Da ist man dann manchmal schon über die Linie hinaus geschossen.
Das ist sicher auch der Grund, warum in dem Asuro-Programm der direkte Weg gewählt wurde.
Gruß
Dirk
@Inka
Wenn ich das richtig sehe, postet ihr da verschiedenen Quellcode.. der eine was von der Base/I2C-Slave, der andere was von der I2C-Master lib?
Grundsätzlich gilt, es gibt Funktionen die die IO-Ports direkt steuern (böse/schnell) und es gibt welche die Rampensteuerung erledigen (gut/lahm). Letztere laufen auch als Task. Die Rampensteuerung auf der Base ist auf Grund des Trägheitsmomentes von Zahnrädern notwendig damit es kein Getriebesalat gibt.
Die I2C-Master Lib muss sich um die Details wie Rampen jedoch eigentlich nicht kümmern wenn sie Fahranweisungen gibt... da sich schon die Base/Slave darum kümmert. Die I2C-Master lib kann eh kein Port der Base direkt ansteuern. Baut man sich ein Linienfolger, lässt man die Software dafür besser auf der Base laufen - schon wegen der trägen Laufzeiten auf dem I2C Bus sammt en/decodierung der Motorbefehle und Übertragungsfehler... und verwendet die Base ports ADC0/1 für den Sensorabgriff. Alles andere ist von hinten durch die Brust ins Auge...
Gruß
Geändert von RolfD (10.03.2014 um 18:42 Uhr)
Sind Sie auch ambivalent?
Lesezeichen