PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C Programmierung Sensoren



peterfb
08.08.2018, 17:30
Hallo,

ich habe folgendes Problem. Ich versuche 3 IR Sensoren mit Simulink für einen fahrenden Roboter in Betrieb zu nehmen und hab ein Problem bei der Logik.
Hier meine Logik

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %
% S1 = Sensor mitte vorne
% S2 = Sensor links vorne
% S3 = Sensor links hinten
% S4 = Sensor rechts hinten
% S5 = Sensor rechts vorne
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %

function [forward, right, left, backward] = Shieldbot(S1, S2, S3, S4, S5)

%% init
forward = 0;
right = 0;
left = 0;
backward = 0;

%% "intelligence"

if (S2 || S1 && S2)
right = 1;
elseif (S5 || S1 && S5)
left = 1;
else
forward = 1;
end



end

Das Problem ist wenn ich eine Ecke anfahre kann es passieren das ich dann zwischen left-right hin und her springe. Das bedeutet ich müsste etwas einbauen das wenn right = 1; ist für eine gewisse zeit left nicht ausgeführt werden kann. Für jede Hilfe wäre ich sehr dankbar.

HaWe
08.08.2018, 17:56
das ist doch kein C...?!

peterfb
08.08.2018, 18:05
das ist matlab aber if und else abfragen sind für mich schon C oder nicht?

HaWe
08.08.2018, 20:30
nein, C hat ganz eigene Syntax und Verknüpfungs-Präferenzen (Operatorrangfolge).
Außerdem sind deine Variablentypen nicht C-typisch definiert.
Es ist für mich als C-Programmierer auch gar nicht klar, wie deine Richtungsvariablen verarbeitet werden.

Was die Verständlichkeit angeht: die Reihenfolge deiner Sx Variablen ist auch nicht sehr intuitiv.

setz doch mal als erstes Klammern um deine einzelnen && und || verknüpften Statements!

- - - Aktualisiert - - -

PS,
als C-Programmierer würde ich eine Variable für die Richtung definieren
int dir;
die dann verschiedene Richtungen als Wert annehmen kann:
#define vor 1
#define rueck -1
#define rechts 2
#define links 4
#define stop 0

if(S1==HIGH) && (S2==HIGH) && (S5==HIGH) {dir=?? } // was dann??
else
if (S3==HIGH) && (S4==HIGH) {dir=??} // was dann??
...usw...

- - - Aktualisiert - - -

PPS,
auch Timer wird man in C sicher ganz anders handhaben als bei dir:


#include <time.h>
#include <sys/time.h>

uint32_t ms;

uint32_t mstimer()
{
struct timeval now;
uint32_t ticks;
gettimeofday(&now, NULL);
ticks=now.tv_sec*1000+now.tv_usec/1000;
return(ticks);
}

dann im Steuer-Code:

bool Ecke=false;
bool Ecke_alt=false;

// Sensoren auswerten
// "intelligence"
// bisherigen Zustand der Eckbedingung speichern
Ecke_alt = Ecke;

// ermitteln, ob eine neue Eckebedingung eingetreten ist
Ecke=.... ??? // hier Ecke-Bedingung ermitteln, wschl über Sensordaten

if (Ecke && !Ecke_alt) { // beim 1.Mal, wenn eine neue Eck-Bedingung eintritt:
ms=mstimer(); // Zeit stoppen
}

// wiederholt Sensoren auswerten, wie du das machst verstehe ich bei deinem Code aber nicht
// "intelligence"
// dann überprüfen, ob ein ungewollter Richtungswechsel passiert ist;

if (dir==links && mstimer()-ms <=2000) { dir=rechts;} // falls ja, einfach wieder auf rechts zurückswitchen


Insgesamt ist mir aber deine Programmstruktur zu unverständlich, da unvollständig oder zumindest nicht C-typisch.

Max Web
09.08.2018, 19:42
Hallo,

Erstmal vorab (das muss einfach sein, da ich vermute, dass Matlab hier zu Bildungszwecken eingesetzt wird): Matlab und C sind zwei vollkommen unterschiedliche Sprachen - If-Abfragen sind ganz normale Sprachkonstrukte, die es in einer Vielzahl von Skript- und Programmiersprachen gibt. Mit C hat das hier absolut nichts zu tun ;)
Natürlich kann es sein, dass der Roboter über eine C-Schnittstelle mit Matlab kommuniziert, aber das ist dann etwas komplett anderes ;)

Du könntest, falls Du es ganz einfach halten möchtest, den vorherigen Fahrbefehl zwischenspeichern und in den Abfragen für die Drehung verwenden.
-> Drehst Du Dich schon nach rechts (vorherige Drehrichtung), so kannst Du nicht nach links drehen, bis eine Geradeausfahrt erreicht ist. Die Linksdrehung muss analog behandelt werden.

Allerdings ist das eher die "triviale Lösung", die noch weit davon entfernt ist, auch nur annähernd perfekt zu sein. Es kann damit immer noch passieren, dass sich der Roboter dann doch lieber etwas mehr Zeit in gewissen Ecken verbringt als geplant ;)
Etwas mehr Sicherheit kriegst Du, indem Du z.B. eine Art "Chaos Drive" einführst, wie es z.B. von älteren Staubsaugerrobotern verwendet wird: Statt sich nur zu drehen, bis die Sensoren "frei" sind, dreht sich der Roboter um einen zufälligen Winkel/eine gewisse Zeit. So kommt man auch aus etwas anderen Ecken heraus.

Grüße,

Max

HaWe
09.08.2018, 21:24
Hallo,
- If-Abfragen sind ganz normale Sprachkonstrukte, die es in einer Vielzahl von Skript- und Programmiersprachen gibt. Mit C hat das hier absolut nichts zu tun

wobei aber auch bedeutsam sein kann, wie die Operatorpreference bei Matlab ist, im Vergleich zu anderen Programmiersprachen:
hat && eine höhere Priorität als || ?
Oder wird einfach von li nach rechts abgearbeitet?

Was ist also
(S2 || S1 && S2) ?
((S2 || S1) && S2) oder (S2 || ( S1 && S2)) ? (letzteres würde C automatisch machen (IIRC), ersteres allerdings, wenn es von li nach re abgearbeitet würde. )
analog bei (S5 || S1 && S5);

- wobei die Assoziativität von einer Reihe von booleschen Verknüpfungen nicht unbedingt trivial oder eindeutig ist, auch wenn man vermuten kann, dass es analog wie bei C gehandhabt wird,
daher meine Bitte, bei mehr als 2 booleschen Verknüpfungen doch besser die Klammern um jeweils ein Paar zu setzen, um es eindeutig zu machen.
(wobei mir diese Tripel aussagenlogisch betrachtet auch etwas suspekt sind , aber ich will das jetzt hier nicht beurteilen)

Max Web
09.08.2018, 21:31
Hallo,


wobei aber auch bedeutsam sein kann, wie die Operatorpreference bei Matlab ist, im Vergleich zu anderen Programmiersprachen:
hat && eine höhere Priorität als || ?
Oder wird einfach von li nach rechts abgearbeitet?

Völlig berechtigter Hinweis, da es wirklich Sprachen geben soll, die das anders handhaben.

Zur Reihenfolge der Operatoren in Matlab: https://www.mathworks.com/help/matlab/matlab_prog/operator-precedence.html , insbesondere:

MATLAB always gives the & operator precedence over the | operator. Although MATLAB typically evaluates expressions from left to right, the expression a|b&c is evaluated as a|(b&c). It is a good idea to use parentheses to explicitly specify the intended precedence of statements containing combinations of & and |.

Reihenfolge der Operatoren in C: https://en.cppreference.com/w/c/language/operator_precedence
-> Es verhält sich in diesem Fall wie C


daher meine Bitte, bei mehr als 2 booleschen Verknüpfungen doch besser die Klammern um jeweils ein Paar zu setzen, um es eindeutig zu machen.
Kann ich zu 100% unterschreiben. Das ist guter Stil und diesen sollte man sich so früh wie möglich aneignen.

Moppi
12.08.2018, 07:14
Ich weiß auch nicht, zu welcher Sprache die Syntax genau gehört, aber intuitiv habe ich das mal beispielhaft umgeschrieben. In der Hoffnung, dass das der gültigen Syntax entsprechen wird. Hoffe, dass Blockbildung mit '{' + '}' funktioniert.

Aufgabe: ich müsste etwas einbauen das wenn right = 1; ist für eine gewisse zeit left nicht ausgeführt werden kann. (und umgekehrt - für geradeaus, soll das auch gelten)




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %
% S1 = Sensor mitte vorne
% S2 = Sensor links vorne
% S3 = Sensor links hinten
% S4 = Sensor rechts hinten
% S5 = Sensor rechts vorne
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %

function [forward, right, left, backward] = Shieldbot(S1, S2, S3, S4, S5)

%% init
forward = 0;
right = 0;
left = 0;
backward = 0;
c1 = 0;
c2 = 100;

%% "intelligence"

if (c1==0 && (S2 || S1 && S2))
{right = 1; c1 = c2;}
elseif (c1==0 && (S5 || S1 && S5))
{left = 1; c1 = c2;}
elseif(c1==0)
forward = 1;
end

if (c1>0) c1 = c1-1;

end

HaWe
12.08.2018, 10:30
(S2 || S1 && S2)
macht keinen Sinn, denn es ist aussagenlogisch nichts anderes als S2 alleine, egal wie S1 ist.
Das gleiche gilt für
(S5 || S1 && S5),
denn das ist nichts anderes als S5 alleine.

Ich vermute daher, dass der gesamte MATLAB code auf noch zu wackeligen Beinen steht und erst einmal neu geschrieben werden müsste.

Moppi
12.08.2018, 11:00
Ja, da hast Du recht. Wenn man das kürzt kann man jeweils den gesamten Ausdruck weglassen bzw. muss man th. nur auf S1 bis S4 prüfen und verzweigen.
Aber keine Ahnung, was sich der Urheber dabei gedacht hat. :)

Ansonsten korrespondiert ja offenbar S1 mit forward, S2 mit right, S3 mit left und S4 mit backward. Also: if(s1)forward=1;if(s2)right=1;if(s3)left=1;

Mal davon abgesehen müsste man die Variablen forward, right, left wieder löschen, wenn jeweils eine andere gesetzt wird. Es sei denn die werden woanders auf 0 gesetzt.