Forum: Compiler & IDEs Nibo 2 Linienverfolgung


von Timo G. (kevin_klein)


Lesenswert?

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
}

von Jan H. (jan_m_h)


Lesenswert?

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.

von Timo G. (kevin_klein)


Lesenswert?

Hi Jan,

Danke für das du mir hilfst.
und wie Programmiert man das mit der Intensität?

von Jan H. (jan_m_h)


Lesenswert?

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.

von Timo G. (kevin_klein)


Lesenswert?

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;
}

von Jan H. (jan_m_h)


Lesenswert?

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
}

von Timo G. (kevin_klein)


Lesenswert?

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?

von Rainer V. (rudi994)


Lesenswert?

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)) {".

von Timo G. (kevin_klein)


Lesenswert?

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 :)

von Rainer V. (rudi994)


Lesenswert?

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.

von Timo G. (kevin_klein)


Lesenswert?

mmh.. der Fehler ist immer noch da... :/ muss wohl irrgendwo anderes 
liegen der Fehler

von Rainer V. (rudi994)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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
1
While (1)
2
 {
3
...
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?

von Jan H. (jan_m_h)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

... 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.

von Karl H. (kbuchegg)


Lesenswert?

> 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.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.