hi @ all
Ich habe es nun geschafft das mein Roboter einer Schwarzen Linie folgen
kann.
Allerdings macht er dies manchmal noch recht ruckartig und es kann
passieren das er von der Linie abkommt und er soll eine strecke abfahren
und am ende im Ziel stehen bleiben aber aufgrund der ruckartigen
Bewegungen bleibt er stehen sobald keiner der beiden Sensoren die
Schwarzen Linie noch erfassen kann.
kann mir jemand sagen, wie ich es schaffe dass er Sauberer und ohne von
der Linie zu kommen fährt?
hier Mein Quellcode: 1 | #include <niboconfig.h>
| 2 | #include <display.h>
| 3 | #include <gfx.h>
| 4 | #include <copro.h>
| 5 | #include <delay.h>
| 6 | #include <iodefs.h>
| 7 | #include <bot.h>
| 8 | #include <avr/interrupt.h>
| 9 | #include <spi.h>
| 10 | #include <stdio.h>
| 11 | #include <leds.h>
| 12 |
| 13 | #include <floor.h>
| 14 | #include "pwm.h"
| 15 | #include "adc.h"
| 16 |
| 17 |
| 18 | #include <avr/interrupt.h>
| 19 | #include <stdint.h>
| 20 | #include <avr/pgmspace.h>
| 21 |
| 22 |
| 23 | #define sense 19
| 24 |
| 25 |
| 26 |
| 27 | int main()
| 28 | {
| 29 | sei();
| 30 | bot_init();
| 31 | spi_init();
| 32 | floor_init();
| 33 | display_init();
| 34 | gfx_init();
| 35 | leds_init();
| 36 | pwm_init();
| 37 |
| 38 | gfx_move (22, 0);
| 39 | gfx_set_proportional (1);
| 40 | gfx_print_text ("Linie folgen");
| 41 | gfx_set_proportional (0);
| 42 |
| 43 | gfx_move (5, 10);
| 44 | gfx_print_char ('R');
| 45 |
| 46 | gfx_move (118, 10);
| 47 | gfx_print_char ('L');
| 48 |
| 49 |
| 50 | copro_ir_startMeasure();
| 51 | delay (10);
| 52 | copro_setSpeedParameters(5, 6, 7);
| 53 | while (1==1)
| 54 | {
| 55 |
| 56 | floor_update();
| 57 | copro_update();
| 58 | char text [20]="-- -- -- -- --";
| 59 |
| 60 | // Bodensensoren
| 61 |
| 62 | floor_update();
| 63 | copro_update();
| 64 | sprintf(text, "%02x %02x %02x %02x",
| 65 | (uint16_t) (floor_relative[FLOOR_RIGHT]/8),
| 66 | (uint16_t) (floor_relative[FLOOR_LEFT]/8),
| 67 | (uint16_t) (floor_relative[LINE_RIGHT]/8),
| 68 | (uint16_t) (floor_relative[LINE_LEFT]/8));
| 69 | gfx_move(22, 30);
| 70 | gfx_print_text(text);
| 71 |
| 72 |
| 73 |
| 74 |
| 75 | if ((floor_relative[LINE_LEFT])<sense && (floor_relative[LINE_RIGHT])<sense)
| 76 | {
| 77 |
| 78 | copro_setSpeed(20,20);
| 79 |
| 80 | }
| 81 |
| 82 | if ((floor_relative[LINE_LEFT])>sense && (floor_relative[LINE_RIGHT])<sense)
| 83 | {
| 84 |
| 85 | copro_setSpeed(15,0);
| 86 |
| 87 | }
| 88 |
| 89 | if ((floor_relative[LINE_LEFT])<sense && (floor_relative[LINE_RIGHT])>sense)
| 90 | {
| 91 |
| 92 | copro_setSpeed(0,15);
| 93 |
| 94 | }
| 95 | if ((floor_relative[LINE_LEFT])>sense && (floor_relative[LINE_RIGHT])>sense)
| 96 | {
| 97 |
| 98 | copro_setSpeed(0,0);
| 99 |
| 100 | }
| 101 | // Spannung
| 102 |
| 103 | bot_update();
| 104 | float volt = 0.0166 * bot_supply - 1.19;
| 105 | sprintf(text, "%3.1fV", (double)volt);
| 106 | gfx_move(30, 10);
| 107 | gfx_set_proportional (1);
| 108 | gfx_print_text("supply: ");
| 109 | gfx_set_proportional (0);
| 110 | gfx_print_text(text);
| 111 |
| 112 | }
| 113 | return 0;
| 114 | }
|
Dein Roboter würde der Linie deutlich flüssiger folgen, wenn du nicht
zwischen links und rechts umschältst, sondern die Geschwindigkeiten
beider Räder aus der Differenz zwischen den Sensoren ausrechnest.
Damit steuert der Roboter unterschiedlich intensiv, je nach dem, wie
weit er von der Linie weg ist.
Viel Erfolg und Spaß noch.
Hi Jan,
Danke für das du mir hilfst.
und wie Programmiert man das mit der Intensität?
Hi Timo
floor_relative[ ] liefert ja einen ganzzahligen Wert. Der hängt mit der
gemessenen Lichtintensität zusammen.
Ich vermute aus deinem Code, dass die Sensoren einen höheren Wert
liefern, wenn es heller wird und die Geschwindigkeit der Motoren mit
copro_setspeed(links,rechts) gesetzt wird?
Wenn ich da was verdreht habe bitte drauf hinweisen.
Dann ziehst du einen der Sensorwerte vom anderen ab. Achtung, die
Differenz kann natürlich negativ sein, also variablentyp beachten.
Dann definierst du eine Grundgeschwindigkeit, und addierst zu ihr bzw
für das andere Rad subtrahierst von ihr die Differenz. Je nach dem, wie
die Werte aussehen solltest du die Differenz vorher noch mit einem
Faktor multiplizieren oder durch einen Faktor teilen.
Du solltest übrigens deinen Code kommentieren, dann verstehen andere
(und auch du selber später) ihn besser.
Hi Jan,
Ja das mit der Lichtintensität und dem setzten der Motoren hast du
richtig verstanden allerdings weiß ich jetzt nicht genau wo du meinst,
dass ich Sensorwerte vom anderen ab ziehe
und ich weiß auch nicht ganz wo ich eine Grundgeschwindigkeit definiert
habe und wann ich davon was abziehen ich werde meinen Quellcode jetzt
mal näher erläutern da ich finde, dass das wirklich eine gute Idee ist
:)
#include <niboconfig.h>
#include <display.h>
#include <gfx.h>
#include <copro.h>
#include <delay.h>
#include <iodefs.h>
#include <bot.h>
#include <avr/interrupt.h>
#include <spi.h>
#include <stdio.h>
#include <leds.h>
#include <floor.h>
#include "pwm.h"
#include "adc.h"
#include <avr/interrupt.h>
#include <stdint.h>
#include <avr/pgmspace.h>
#define sense 19
define sense gibt den Vergleichswert der Helligkeit an
int main()
{
sei();
bot_init();
spi_init();
floor_init();
display_init();
gfx_init();
leds_init();
pwm_init();
gfx_move (22, 0);
gfx_set_proportional (1);
gfx_print_text ("Linie folgen");
gfx_set_proportional (0);
gfx_move (5, 10);
gfx_print_char ('R');
gfx_move (118, 10);
gfx_print_char ('L');
copro_ir_startMeasure();
delay (10);
copro_setSpeedParameters(5, 6, 7);
while (1==1)
{
floor_update();
copro_update();
char text [20]="-- -- -- -- --";
// Bodensensoren
hier nimmt der Bodensensor die werte auf
floor_update();
copro_update();
sprintf(text, "%02x %02x %02x %02x",
(uint16_t) (floor_relative[FLOOR_RIGHT]/8),
(uint16_t) (floor_relative[FLOOR_LEFT]/8),
(uint16_t) (floor_relative[LINE_RIGHT]/8),
(uint16_t) (floor_relative[LINE_LEFT]/8));
gfx_move(22, 30);
gfx_print_text(text);
Hier kommen nun mehrer If schleifen welche dafür sorgen,
dass 1. der Roboter gerade ausfährt sollte der gemessen Wert links und
rechts kleiner als 19 sein
if ((floor_relative[LINE_LEFT])<sense &&
(floor_relative[LINE_RIGHT])<sense)
{
copro_setSpeed(20,20);
}
2. sollte der Wert links größer sein als 19 macht er einen Korrekturzug
nach rechts in dem das rechte Rad stehen bleibt und das linke dreht
if ((floor_relative[LINE_LEFT])>sense &&
(floor_relative[LINE_RIGHT])<sense)
{
copro_setSpeed(15,0);
}
3. sollte der wert rechts größer sein als 19 macht er einen Korrekturzug
nach links in dem das linke Rad stehen bleibt und das rechte dreht.
if ((floor_relative[LINE_LEFT])<sense &&
(floor_relative[LINE_RIGHT])>sense)
{
copro_setSpeed(0,15);
}
if ((floor_relative[LINE_LEFT])>sense &&
(floor_relative[LINE_RIGHT])>sense)
und 4. sollten Beide werte größer sein als 19 solle der Roboter stehen
bleiben.
{
copro_setSpeed(0,0);
}
// Spannung
bot_update();
float volt = 0.0166 * bot_supply - 1.19;
sprintf(text, "%3.1fV", (double)volt);
gfx_move(30, 10);
gfx_set_proportional (1);
gfx_print_text("supply: ");
gfx_set_proportional (0);
gfx_print_text(text);
}
return 0;
}
Ich zeig am besten wie ich es meine. Der Pseudocode da unten orientiert
sich etwas an C und deinem Programm von oben. 1 | #define sense 19
| 2 | // Schwelle, ab der der roboter stehen bleibt
| 3 |
| 4 | #define sensitivity 1
| 5 | // empfindlichkeit der kurvenfahrt
| 6 |
| 7 |
| 8 | #define speed 16
| 9 | //Geschwindigkeit bei der gradeausfahrt
| 10 |
| 11 | While(1)
| 12 | {
| 13 | floor.update();
| 14 | diff =(floor_relative[LINE_RIGHT] - floor_relative[LINE_LEFT]) * sensitivity
| 15 |
| 16 | If ((floor_relative[LINE_RIGHT] > sense) && (floor_relative[LINE_LEFT] > sense)) {
| 17 | copro_setSpeed(0,0)
| 18 | } else {
| 19 | copro_setSpeed(speed - diff, speed + diff)
| 20 | }
| 21 | }
|
Hi Jan,
ich habe es nun eingebaut und glaube nun zu verstehen wie du es meinst
und denke das die durchaus funktionieren könnte
allerdings weiß ich gerade nicht wo mein Fehler ist ich schreib jetzt
nur die neuen teile des Quellcodes rein der Rest ist gleich wie vorhin 1 | #define sense 19
| 2 | #define sensitivity 1
| 3 | #define speed 16
| 4 |
| 5 |
| 6 | While (1)
| 7 | {
| 8 | floor.update();
| 9 | diff =(floor_relative[LINE_RIGHT] - floor_relative[LINE_LEFT]) *
| 10 | sensitivity
| 11 |
| 12 | If ((floor_relative[LINE_RIGHT] > sense) && (floor_relative[LINE_LEFT]
| 13 | > sense)) {
| 14 | copro_setSpeed(0,0)
| 15 | } else {
| 16 | copro_setSpeed(speed - diff, speed + diff)
| 17 | }
| 18 |
| 19 | }
| 20 |
| 21 |
| 22 | }
| 23 | return 0;
| 24 | }
|
jetzt kommt allerdings diese Fehler Meldung
../Nibo_blinken.c:47: error: expected ';' before '{' token
was muss ich machen?
Semikolon (;) fehlt, zudem sind bis zu mehrere geschweifte Klammern
zuviel oder vor While() fehlt die Zeile "int main() {".
Code-Schnipsel sollten in einem Posting als Code formatiert werden,
siehe unten unter "Antwort schreiben". Ohne Formatierung passieren
merkwürdige Dinge, wie im Beitrag zuvor in Zeile "> sense)) {".
hi Rainer,
ich merke gerade die frage war falsch gestellt ich wollte wissen an
welche stelle die Semikolon muss und "int main () {" ist vorhanden ich
habe im letzten Post nur die Änderungen zu dem davor gemacht würde mir
freuen wenn du es dir angucken könntest vlt. findest du ja den Fehler
bzw den Ort an dem das Semikolon fehlt :)
Deinen Code kann ich leider nicht kompilieren, habe hier nur C/Cpp unter
CodeBlocks. Da fehlen mir Deine Bibliotheken, Groß-/Kleinschreibung und
Semikolon wird anders gehandhabt und ich wüßte nicht, wo die fehlerhafte
Zeile 47 sein soll. Ich würde hinter "diff=... sensivity" und hinter den
Zeilen mit "copro_setSpeed()..." ein Semikolon setzen.
mmh.. der Fehler ist immer noch da... :/ muss wohl irrgendwo anderes
liegen der Fehler
Fehler gefunden? Übrigends können Fehler wg. z.B. fehlendem Semikolon
auch in der Bibliothek bzw. Header-Dateien o.a. vorkommen. Die werden ja
nicht von Göttern programmiert, sondern von Leuten, die bis spät in der
Nacht am PC sitzen und literweise Kaffee in Code konvertieren. Hier bei
Codeblocks mit MinGW sind solche Fehler schon mal aufgefallen, je nach
dem, was da über bedingte Compilierung eingebunden wurde. LG
Timo G. schrieb:
> jetzt kommt allerdings diese Fehler Meldung
> ../Nibo_blinken.c:47: error: expected ';' before '{' token
> was muss ich machen?
Den C Code nicht einfachg nur kopieren, sondern lesen und dann mal alle
Tippfehler wie zb Schlüsselwörter die mit einem Grossbuchstaben anfangen
korrigieren. In C gibt es kein einziges Schlüsselwort, welches mit einem
Grossbuchstaben anfängt
ah ja. seit wann schreibt sich 'while' mit einem großen 'W'.
1 | ....
| 2 | If ((floor_relative[LINE_RIGHT] > sense) && (floor_relative[LINE_LEFT]
| 3 | ....
|
und 'if' beginnt immer noch mit dem Kleinbuchstaben 'i'.
Und nein: Eine Fehlermeldung 'Semikolon missing' bedeutet nicht
unbedingt immer, dass da tatsächlich irgendwo eines fehlt. Oft genug
bedeutet es ganz einfach nur: korrigier einfach mal alle Tippfehler -
mit dem Quatsch den du da geschrieben hast, kann ich nicht viel
anfangen.
PS: wieso ist das eigentlich im Off-Topic?
Also, ich hatte das von mir ja schon als Pseudocode bezeichnet, weil es
KEIN richtiger Code ist. Die Groß-Klein-Schreibung hat bei mir halt mein
Handy so gemacht. Hätte ich vielleicht deutlicher machen sollen, dass
das niemals tatsächlichen C-Code hätte darstellen sollen.
... und ja.
Einfach alle Programmzeilen in einer Wurscht am linken Bildschirmrand
runterschreiben ist ein sicherer Garant dafür, dass man über kurz oder
lang (eher kurz) den Überblick verliert, welche schliessende }
eigentlich zu welcher öffnenden { gehört.
> Hier kommen nun mehrer If schleifen
Es gibt keine if - "Schleifen".
Zum Wesen einer Schleife gehört es unweigerlich, dass irgendetwas
wiederholt werden kann. Darum heisst es Schleife, wie die Schleife in
einem Tonband, dessen Enden zusammengeklebt sind und das deshalb
automatisch vom Gerät wieder und immer wieder abgespielt wird.
Ein if wiederholt nichts. Ein if trifft eine Entscheidung und wählt je
nach Ausgang der Entscheidung einen von 2 Codepfaden.
Also kann es keine Schleife sein.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|