[leicht bis schwer]Ampelsteuerung & Sicherheit

CDW

Moderator
Mitarbeiter
#1
Es soll eine kleine Ampelsteuerung geschrieben werden. Diese soll auf Ereignisse reagieren und entsprechende Lichtzeichen setzen.
Das Hauptaugenmerk liegt dabei nicht auf der einzelnen "low-level" Umschaltvorgängen, sondern auf der Sicherheit der Verkehrsteilnehmer.
Wir gehen einfach davon aus, dass ein automatischer Übersetzer "verwendete Programmiersprache" -> Microcontrollercode existiert
und nutzen das Programm als Prototyp der endgültigen Implementierung.

Die Aufgabe ist in 2 Teilaufgaben aufgespalten (je nach Zeit/Lust reicht schon die erste aus ;) )
Die Umsetzung dürfte vom Code her kürzer, als die Beschreibung, sein (also nicht abschrecken lassen ;) )
Man soll sich im wesentlichen um "logsiche" Sicherheitsaspekte Gedanken machen - hierzu liefert die detailierte Beschreibung
einige Ansätze.

Eine ganz einfache Kreuzung:
Code:
                    |         |         |
                    |         |    .    |
                    |         |   /|\   |
                    |         |    |    |
                    |         |    |    |
                    |#########|         |
                 (F)| |  |  | | |  |  | | (F)
                 (1)| |  |  | | |  |  | | (1)
                    | |  |  | | |  |  | |
          (F)(2)    |         |         |       (F)(2)
  ------------------ (A)(1)( )           -------------------------
          -------                     (A)    ------- ##
   /____                              (2)            ##
   \      -------                     ( )    ------- ##
                                                     ##
  -------------------                    -------------------------
       ## -------   (A)                      -------
       ##           (2)                               _____\
       ## -------   ( )                      -------       /
       ##
  -------------------          (A)(1)( ) -------------------------
          (F)(2)    |         |         |       (F)(2)
                    | |  |  | | |  |  | |
                 (F)| |  |  | | |  |  | |(F)
                 (1)| |  |  | | |  |  | |(1)
                    |         |#########|
                    |    |    |         |
                    |    |    |         |
                    |   \|/   |         |
                    |    '    |         |
                    |         |         |
Es gibt 2 Fussgängerampeln (F1 und F2) und 2 Autoampeln (A1,A2).
Hauptstrasse = senkrecht
Querstrasse = waagerecht
(anfangs hatte ich eine deutlich komplizierte Kreuzung geplant - mit Linksabbiegespuren und entsprechenden Ampeln. Falls die Aufgabe zu einfach wird, kommt diese auch dran ;) )

Eine Autoampel hat 4 Zustände: {grün,rot,zwischen,notbetrieb}
Eine Fussgängerampel hat 3 Zustände {grün, rot, notbetrieb}
Für die "Ampelschaltung" reicht es aus, einer Ampel(variable,array, was auch immer) den jeweiligen Zustand zuzuweisen.
Die Fussgängerampeln sind Bedarfsampeln. Sie sollen also nur dann überhaupt auf grün geschaltet werden, wenn ein Signal von einem Fussgänger kommt (Knopf). Und zwar möglichst in der nächsten sinnvoll verfügbaren Phase (es sollen also nicht sofort alle Autoampeln auf rot gestellt werden ;) )

Die Autoampeln sollen je nach Tagesszeit zwischen Zeit-und Bedarfsmodus wechseln können.
Die Ampeln im Zeitmodus sollen jeweils nacheinander den Verkehrsteilnehmern die Durchfahrt ermöglichen. Im Bedarfsmodus
soll der Verkehr auf der Hauptstrasse grün haben und Querstrassenverkehr nur bei Bedarf grün geschaltet bekommen ("Bedarf" = Sensoren, die ein Auto feststellen)

Keine Angst, ihr müsst keine Sensoren abfragen oder Zeit bestimmen ;)

Da es sich um eine sicherheitskritische Anwendung handelt, sollte die Implementierung in mindestens 2 Module aufgespalten werden.
Ein Modul kümmert sich unmittelbar um die richtige Schaltung und ein Modul reagiert auf die Außenwelt und kümmert sich nur um die "timings".

Das "Schaltmodul" implementiert:
peds_go(eine Fussgängerampel: F1 oder F2)
peds_stop(eine Fussgängerampel: F1 oder F2)
cars_go(eine Autoampel: A1 oder A2)
cars_stop(eine Autoampel: A1 oder A2)
cars_yellow(eine Autoampel: A1 oder A2)
error(): es wurde ein Hardwaredefekt festgestellt, die Ampel soll in den Notbetriebmodus gehen.

dabei soll "yellow" die Umschaltung zur Grünphase/Rotphase der jeweiligen Ampel vorbereiten (also Zwischenphase einleiten), "go" entsprechend grün setzen,
"stop" auf rot setzen

Es gibt folgende Schnittstellen zur Außenwelt, die euer Programm in einem Modul implementieren soll:
init(): das Signal kommt, wenn die Anlage in Betrieb genommen wird. Hier können notwendige Initialisierungen vorgenommen werden.
tick(): wenn ein Zeitabschnitt vergeht. Wird automatisch von einer Zeitgebereinheit aufgerufen.
require_peds({eine der Fussgängerampeln: F1 oder F2}) : Signal einer Fussgängerampel(Knopf/Berührfläche).
require_cars({A2}) : Signal von einem Sensor
set_mode(Zeit oder Bedarf)
error(): es wurde ein Hardwaredefekt festgestellt, die Ampel soll in den Notbetriebmodus gehen.

Prinzipiell müsste noch sowas wie "set_time_slices" rein, damit die Verkehrzentrale die Dauer der Grün/Zwischenphasen der jeweiligen Ampeln dem Verkehrsaufkommen anpassen kann - der einfachheitshalber lassen wir das mal weg ;) .

Die Software selbst hat KEINE Möglichkeit die Zeit zu messen. Sie soll nur auf die Events von der Außenwelt reagieren und entsprechende Ampeln setzen. Zum setzen soll das "Außenweltmodul" nur die Schnittstellen des Schaltmoduls nutzen (Funktion/Methodenaufruf oder Event feuern - je nach Sprache/Umsetzung).
Das Schaltmodul ist für das korrekte Setzen der Lichtsignale verantwortlich! Die Sicherheit soll NICHT von der richtigen Reihenfolge der Aufrufe abhängen! Es soll also unmöglich sein, von "außen" einen ungültigen Zustand zu setzen. Notfalls soll die Funktion einen Fehler signalisieren (Fehlervariable, Rückgabewert usw.) und keine Aktion durchführen.

:
Zeitfenster für die Grünphase/Zwischenphase:
der einfachheitshalber konstant (und Pi * Daumen festgelegt, falls es nicht passen sollte, können diese natürlich auch geändert werden)

Dauer der Zwischenphase(gelb): 1 Tick
Fussgängerampeln: bei Bedarf 3 Ticks(grün), sowie 2 Ticks für "Nachzügler" (die Ampel ist schon rot, es dürfen aber hier noch keine Autos fahren).

Zeitmodus:
Hauptstrassenverkehr(grün): 10 Ticks
Querstrassenverkehr(grün): 5 Ticks

Im Bedarfsmodus:
Hauptstrassenverkehr: default grün
Querstrassenverkehr(grün): bei Bedarf 2 Ticks

1. Ampeln der Hauptstrasse auf grün <=> Querstrassenampeln auf rot(kein gelb, kein grün!) und umgekehrt.
Es darf NIEMALS dazu kommen, dass beide Richtungen auch nur für kurze Zeit gleichzeitig grün- und/oder zwischenphase zeigen.

2. Fussgängerampeln zeigen grün: nur parallel verlaufender Autoverkehr erlaubt.

3. (Teilaufgabe2) Fussgänger können sich nicht teleportieren ;). Also dürfen Autofahrer nicht sofort grün bekommen, sondern es muss eine Mindestzeit für "Nachzügler" vergehen (siehe oben).

4. Autoampeln dürfen nicht direkt zwischen grün und rot wechseln (dafür gibt es die Zwischenphase gelb)

5. Deadlocks sollten möglichst vermieden werden.

6. denkt euch weitere Punkte aus ;)
Teilaufgabe 1: setzte ein Schaltmodul um. Es geht also nur um das Setzen der Lichtzeichen.
Dabei soll eine Ausgabe der Ampelzustände sowie eine Interaktion möglich sein(Konsole reicht aus) - Umsetzung z.B als Extramodul/Code der die Funktionen aufruft:
Code:
1.peds_go
2.peds_stop
3.cars_go
4.cars_stop
5.cars_yellow
6.error
your input:
Teilaufgabe 2: setzte das "Außenwelt" Modul um, dieses soll die Schnittstellen des Schaltmoduls nutzen, um die Ampelzustände zu setzen. Hier geht es daru, die Lichtzeichen entsprechend einem "Programm" zu setzen (also "live-schaltung"
Ausgabe der Lichtzeichen sowie einfache Interaktion (Konsole reicht aus) soll möglich sein:
Code:
1.next tick
2.switch_mode
3.require_peds(F1)
4.require_peds(F2)
5.require_cars(A2)
6.error
your input:

Überlegt euch, wie man eine mögliche Fehlerfreiheit/Korrektheit des Codes erreicht (optimalerweise nachweist).
Tipp: Testcases sowie einfacher, schrittweise nachvollziehbarer Code wären ein Anfang. Es geht hier also nicht um möglichst elegange Lösungen mit spezifischen Sprachtricks (OOP, x?y:z) sondern um Nachvollziehbarkeit ;).
Bitte keine Triviallösungen (alle Autoampeln auf rot => Fussgänger auf grün).
 
Zuletzt bearbeitet:

CDW

Moderator
Mitarbeiter
#2
Hm, die lange Beschreibung schreckt wohl ab.

Die tatsächliche Implementierung kann sehr kurz gehalten werden ;)

Hier eine Beispielimplementierung der Aufgabe 1 (allerdings auf eine einfache Fussgängerampel beschränkt ;) )
Code:
                    |#########| (A)( )( )  |
                 (F)| |  |  | | |  |  | | 
                 ( )| |  |  | | |  |  | | 
                    | |  |  | | |  |  | |
                    |         |######### | 
                    (A)( )( )
(falls meine ASCII-zeichen-skillz nicht ausreichend sind: eine Fussgängerampel über eine Strasse. Zusammen mit einer Autoampel)

Bei zwei Operationen (cars_go und peds_go) wurde über Korrektheit argumentiert. Wie man sieht, besteht der Großteil des Codes aus Kommentaren.
PHP:
public class LightControl
{
    /*
     * Entwurf: Eine Ampel kann rot,grün,gelb und "notbetrieb" anzeigen: 
     * SIGNAL = {RED,GREEN,YELLOW,EMERGENCY}; 
     * Die Ampelzustände werden in 2 Variablen
     * festgehalten: traffic_lights und ped_lights.
     * Datentyp der Ampelzustände:
     * SIGNAL, wobei die Fussgängerampel kein gelb anzeigen kann. 
     * 
     * Anforderungen: 
     * a) Fussgängerampel kann nur dann grün sein, wenn die Autoampel rot
     * ist (kein gelb, und natürlich kein grün). 
     * Also: 
     * 1. Ist die Fussgängerampel grün, so muss die Autoampel rot sein: 
     * (peds_light = GREEN => traffic_light = RED) 
     * 
     * b) Zeigt die Autoampel etwas anderes als rot, so darf die Fussgängerampel
     * nur rot sein.
     * 2.Also: ist die Autoampel grün oder gelb, so muss die
     * Fussgängerampel rot sein 
     * traffic_light ∈ {GREEN,YELLOW} => peds_light = RED
     * 
     * c) Ist der Notbetriebmodus für eine der Ampeln an, so muss dieser auch
     * für die andere Ampel eingeschaltet sein:
     * 3.((traffic_light = EMERGENCY) <=> (peds_light = EMERGENCY))
     * 
     * d) Autoampel darf nicht direkt zwischen grün und rot wechseln (nur
     *    über die Zwischenphase gelb)
     * 4. --
     * 
     * Wir gehen davon aus, dass eine Operation in einem gültigen Zustand
     * startet und müssen nur dafür sorgen, dass die Operation diesen Zustand
     * nicht verletzt. Erzeugt keine der Operationen einen ungültigen Zustand 
     * läuft das ganze Programm korrekt ab ;)
     */
    protected enum SIGNAL {RED,GREEN,YELLOW,EMERGENCY};
    protected class InvalidOperation extends Exception 
    {
        InvalidOperation(String err)
        {super(err);}
    };
    
    /* Initialzustand: alle Anforderungen erfüllt */
    private SIGNAL traffic_light = SIGNAL.GREEN;
    private SIGNAL peds_light = SIGNAL.RED;
    
    public LightControl()
    {
        this.traffic_light = SIGNAL.GREEN;
        this.peds_light = SIGNAL.RED;
    }
    
    /* peds_go() setzt: peds_light = GREEN
     * Annahme: gültiger Zustand. Also traffic_light ∈ {GREEN,YELLOW,RED,EMERG}
     * peds_light ∈ {GREEN,RED,EMERG}
     * 
     * Wir müssen nur sicherstellen, dass traffic_light == RED, bevor wir 
     * peds_light = GREEN setzen. Begründung:
     *
     *  Ist traffic_light == RED, so ist die Aussage
     *  traffic_light /∈ {GREEN,YELLOW,EMERG}
     *  äquivalent => also ist peds_light entweder GREEN
     *  oder RED (Anforderungenn 2,3 erfüllt). Wird peds_light zu GREEN
     *  wird die 1 Anforderung nicht verletzt. 
     *  Anforderung 4 bleibt unverletzt, da traffic_light nicht verändert wird
     * 
     * Wenn wir also peds_light = GREEN nur dann setzen, wenn 
     * traffic_light == RED ist, bleiben wir im gültigen Zustandsraum.
     */
    public void peds_go() throws InvalidOperation
    {
        if (this.traffic_light == SIGNAL.RED)
            this.peds_light = SIGNAL.GREEN;
        else
            throw new InvalidOperation("Traffic light is not red!");
    }

    public void peds_stop() throws InvalidOperation
    {
        if (this.traffic_light != SIGNAL.EMERGENCY)
            peds_light = SIGNAL.RED;
        else
            throw new InvalidOperation("Not allowed in emergency mode!");
    }
    /* cars_go() setzt: traffic_light = GREEN
     * Annahme: gültiger Zustand. Also traffic_light ∈ {GREEN,YELLOW,RED,EMERG}
     * peds_light ∈ {GREEN,RED,EMERG}
     * 
     * Wenn traffic_light == YELLOW (und optional peds_light == RED), so kann
     * traffic_light = GREEN gesetzt werden. Begründung:
     *
     * Ist traffic_light = YELLOW, so ist die Aussage
     * traffic_light not ∈ {GREEN,EMERG,RED} äquivalent. 
     *  => Also Anforderung 3 erfüllt, da wir uns nicht im EMERGENCY Modus befinden
     *
     * Ist traffic_light = YELLOW, so ist auch die Anforderung 4 erfüllt (wir schalten also
     * nicht direkt von rot auf grün)
     * Bleiben noch Anf 1 und 2.
     * 
     * Ist peds_light = RED, so wird die Anforderung 1 nicht verletzt und gemäß der Anforderung 2 
     * kann traffic_light entweder den Wert GREEN oder YELLOW annehmen 
     * (Anf 2. ist somit erfüllt:
     *  traffic_light = GREEN => peds_light = RED )
     * wobei peds_light = RED auch aus der Annahme, dass die Operation in einem
     * gültigen Zustandsraum startet (und daher Anforderung 2 gilt, 
     * d.h traffic_light = YELLOW nur bei peds_light = RED gesetzt werden konnte) 
     * herausfolgen kann und nicht extra sichergestellt werden muss.
     *
     * Wenn also traffic_light = GREEN nur dann gesetzt wird, wenn vorher 
     * traffic_light == YELLOW war (und optional: peds_light == RED), bleiben wir im
     * gültigen Zustandsraum
     */
   
    public void cars_go() throws InvalidOperation
    {
        if ((this.traffic_light == SIGNAL.YELLOW) && (peds_light == SIGNAL.RED))
            traffic_light = SIGNAL.GREEN;
        else
            throw new InvalidOperation(
                    "Traffic light is not yellow or peds light is not red!");
    }

    public void cars_stop() throws InvalidOperation
    {
        if (this.traffic_light == SIGNAL.YELLOW)
            this.traffic_light = SIGNAL.RED;
        else
            throw new InvalidOperation("Traffic light is not yellow!");
        
    }
    public void cars_yellow() throws InvalidOperation
    {
        if (this.peds_light == SIGNAL.RED)
            this.traffic_light = SIGNAL.YELLOW;
        else
            throw new InvalidOperation("Peds light is not red!");
    }
    
    public void error()
    {
        this.traffic_light = SIGNAL.EMERGENCY;
        this.peds_light = SIGNAL.EMERGENCY;
    }
    
    
    public SIGNAL getTrafficLight()
    {
        return this.traffic_light;
    }
    
    public SIGNAL getPedsLight()
    {
        return this.peds_light;
    }
    
}
Komplettes Projekt (Aufruf:
java GUI)
 
Zuletzt bearbeitet:
#3
Keine Angst Teilaufgabe 1 steht schon mehr oder minder.
Eine kleine Frage bezüglich der Zustände.
Ist "aus" kein Zustand ?
{aus,grün,rot,zwischen,notbetrieb} Sieht für mich nach 5 Zuständen aus.

Dieser Post wird editiert wenn ich fertig bin.
 

CDW

Moderator
Mitarbeiter
#4
Eine kleine Frage bezüglich der Zustände.
Ist "aus" kein Zustand ?
{aus,grün,rot,zwischen,notbetrieb} Sieht für mich nach 5 Zuständen aus.
Ups, danke. Das Gleiche ist auch bei Fussgängern.
Werde es gleich korrigieren, damit es nicht so verwirrend ist.

Allerdings ist es imho eine Definitions/Betrachtungssache: sofern die Steuerung an ist, ist die Ampel auch "an" bzw. wenn diese "aus" ist, kann die Steuerung auch keine Lichtzeichen setzen.

Hm, ob eine "korrekt funktionierende" Ampel nun immer irgendwas anzeigen muss (zumindest das Notfallprogramm fahren) oder auch mal "dunkel" sein kann?
Für die Aufgabe definieren wir einfach mal, dass eine korrekt funktionierende Ampel über 4 Zustände {rot,grün,gelb,notbetrieb} verfügt und AUS bedeutet dann "komplett" aus (also auch die Steuerung - daher ein "uninteressanter" Zustand).
Wer schon "aus" in seinem Code/Entwurf berücksichtigt hat, braucht es aber nicht extra zu ändern.
 
#5
Modelliert

Da in der Aufgabe ausdrücklich steht, das es um Nachvollziehbarkeit bzw. gute Dokumentation geht, habe ich das ganze erst einmal modelliert.

In dem UML Diagramm ist nun das zu sehen was ich bis jetzt mal aus der Aufgabenstellung an Infos entnommen habe. Den Zeitgeber würde ich Thread gesteuert realisieren, damit auch parallel entsprechende Ticks (aufrufe von tick() ) generiert werden können.

Bitte um kurze Rückmeldung, ob ich soweit richtig liege?

Anmerkung: Attribute habe ich erst einmal weggelassen, weil diese an dieser Stelle erst einmal uninteressant sind.

Mit freundlichen Grüßen

Christian
 
Zuletzt bearbeitet:
#7
Meine Lösung

Söö ich habe das ganze in C realisiert.
Und habe die Module durch entsprechende Header und Quellcodedateien realisiert. Ich habe es so realisiert das die beiden Fußgängerampeln F1 und F2 unabhängig von einander (durch Threads) laufen und auch auf Ereignisse sprich Taster reagieren können. Betätigt ein Fußgänger den Taster kommt die Grünphase schon nach 1 Tick und nicht erst nach 3 Ticks.

Threadsteuerung in Modul Zeitgeber und Schaltmodul. Die Aussenwelt stellt nur die Benutzerschnittstellen nach außen bereit z.B. init() um die Anlage hoch zu fahren.

Habe das ganze der besseren Übersichtlichkeit ausreichend Kommentiert!

ANMERKUNG: Ich wollte es eigentlich über C++ objektorientiert umsetzen, allerdings konnte ich da pthread.h nicht nutzen. Für da effizient mit Threads zu arbeiten brauche ich Boost und das habe ich noch nicht...


Mit freundlichen Grüßen

Christian

Zeitgeber.h

Code:
/*
     - Zeitgeber:
        Thread der sekündlich eine tick() Funktion aufruft.
            --> tick() ist bestandteil eines anderen Moduls!
                    --> Namens: Aussenwelt
*/

#ifndef __ZEITGEBER__H
#define __ZEITGEBER__H

void start(); /* start the timer (Thread) */
void * tickThread (void * pt); /* the thread */




#endif
Zeitgeber.c

Code:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include "Zeitgeber.h"
#include "Aussenwelt.h"

int status=0; /* is thread enabled? */

void * tickThread (void * pt) { /* one times pro second call tick() */
    while(1) {
        sleep(1);
        /* printf("tickThread\n"); */
        tick(); /* call tick() in Aussenwelt */    
}

    pthread_exit(NULL);

}


void start() { /* start the thread tickThread() */
    pthread_t thread;
    int tr;
    if(!status) {
        
        tr =pthread_create(&thread,NULL,tickThread,NULL);    
        if (tr) {
            printf("Fehler in init() %d \n",tr);
            exit(1);
}
}
    

}
Schaltmodul.h

Code:
#ifndef __SCHALTMODUL__H
#define __SCHALTMODUL__H

enum Light { off,red, green ,yellow};
typedef enum Light Light; /* data type for traffic light phase */

void startSwitchingModule(); /* activated necessary threads */
void * triggerF1(void *pt); 
void * triggerF2(void *pt);
Light getLight(int); /* handover the light phase */
char * ausgabe(int);


#endif
Schaltmodul.c

Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "Zeitgeber.h"
#include "Aussenwelt.h"
#include "schaltmodul.h"


static Light F1; /* for foot traffic light F1 */
static Light F2; /* for foot traffic light F1 */

char * ausgabe(int value) {
    switch (value) {
        case off: return "off";
        case red: return "red";
        case green: return "green";
        case yellow: return "yellow";
        default: printf("Keine korrekte Farbe!\n");
}
}

Light getLight(int value) {
    int i;
    if ((value >=0) && (value <=1)) {
        if (!value) {
            return F1;
            
}
        else {
            return F2;
}


}

}

void * triggerF1(void *pt) {
    while (1) {
         /* sleep(1);
        printf("triggerF1\n"); */
        int start, ende;
        int seconds;
        start = getTicks();
        Light status = getLight(0);
        switch (status) {
            case off: F1 = red;
            case red: if (getFootbridge(0)){
                    seconds =1;
                    resetFootbridge(0);
                    sleep(1);
                
}
                  else {
                    seconds =3;
                    sleep(3);
}
                 ende = getTicks(); 
                 if (((ende-start) == seconds)) F1 = green; 
                 break;
            case green: sleep(5);
                ende = getTicks();
                  if ((ende-start) == 5) F1 = red;

}
        /*printf("Ticks: %ld \n",getTicks()); */
        printf("foot traffic light F1: %s\n",ausgabe(F1));
}
    
}

void * triggerF2(void *pt) {
    while (1) {
         /* sleep(1);
        printf("triggerF1\n"); */
        int start, ende;
        int seconds;
        start = getTicks();
        Light status = getLight(1);
        switch (status) {
            case off: F2 = red;
            case red: if (getFootbridge(1)){
                    seconds =1;
                    resetFootbridge(1);
                    sleep(1);
                
}
                  else {
                    seconds =3;
                    sleep(3);
}
                 ende = getTicks(); 
                 if (((ende-start) == seconds)) F2 = green; 
                 break;
            case green: sleep(5);
                ende = getTicks();
                  if ((ende-start) == 5) F2 = red;

}
        
        printf("foot traffic light F1: %s\n",ausgabe(F2));
}
    
}

void startSwitchingModule() {
    pthread_t thread1, thread2;
    int tr1,tr2;
    tr1 = pthread_create(&thread1,NULL,triggerF1,NULL);
    tr2 = pthread_create(&thread2,NULL,triggerF2,NULL);

    if (tr1 && tr2) {
        printf("Error by threads in startSwitchingModule!\n");
        exit(1);
}
}
Aussenwelt.h

Code:
#ifndef __AUSSENWELT__H
#define __AUSSENWELT__H

void init(); /* activated the system. */
void tick(); /* counts the ticks from tickThread() */
long getTicks(); /* handover number from ticks */
void setFootbridge(int); /* signal coming from footbridge. */
void setSensor(int); /* signal coming from trafic light */
int getFootbridge(int); /* handover of value from foot traffic light sensor status. */
int getSensor(int);
void resetFootbridge(int); /* reset sensor status for foot traffic light F1 or F2 */



#endif
Aussenwelt.c

Code:
#include "Aussenwelt.h"
#include "Zeitgeber.h"
#include "schaltmodul.h"

static long numberTicks; /* number from ticks */
static int footbridge[2]; /* coming from footbridge sensor a signal? */
static int traficLight[2]; /* coming from trafic light sensor a signal? */

void tick() { 
    numberTicks++;
}

long getTicks() {
    return numberTicks;
}

void init() {
    start(); /* start the timer */
    startSwitchingModule(); /* activated SwitchingModule  */
}

void setFootbridge(int ampel) {
    /* 
        0 is footbridge F1
        1 is footbridge F2

*/
    if ((ampel >=0) && (ampel <=1)) {
        if (!footbridge[ampel]) {
            footbridge[ampel] = 1;
}
}
}

void setSensor(int sensor) {
    /*
        0 is sensor S1
        1 is sensor S2
*/
    if ((sensor >=0) && (sensor <=1)) {
        if (!traficLight[sensor]) {
            traficLight[sensor] = 1;
}
}

}

int getFootbridge(int value) {
    if ((value >=0) && (value <=1)) {
        return footbridge[value];
}
}

int getSensor(int value) {
    if ((value >=0) && (value <=1)) {
        return traficLight[value];
}    
}

void resetFootbridge(int value) {
    if ((value >=0) && (value <=1)) {
        footbridge[value] =0;
}

}
 
Zuletzt bearbeitet:
#8
ANMERKUNG: Ich wollte es eigentlich über C++ objektorientiert umsetzen, allerdings konnte ich da pthread.h nicht nutzen. Für da effizient mit Threads zu arbeiten brauche ich Boost und das habe ich noch nicht...
Du musst nur einen ordentlichen Compiler haben (MS Visual Studio, Clang, GCC), der C++11 kann und dann kommst du auch ohne boost aus.
Die STL enthält nämlich seit dem 11er standard eine thread Klasse.
Siehe: thread - C++ Reference

Das ist meiner Meinung nach sogar einfacher zu verwenden als pthreads, weil du die Parameter an den thread direkt weiterleiten kannst - fast wie bei einem Funktionsaufruf.

Wichtig: thread immer joinen (.join()) oder detachen (.detach()) bevor er out-of-scope geht.
 
Oben