BWP-SS19-01/Fein Design/Haupt-Steuerung

Aus Verteilte Systeme - Wiki
< BWP-SS19-01‎ | Fein Design
Version vom 25. August 2019, 15:52 Uhr von Jhebe001 (Diskussion | Beiträge) (→‎Main_Control)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springen Zur Suche springen

Haupt-Steuerung

Der Grund für die verwendete Systemstruktur ist, dass über den Haupt-Thread die einzelnen Modul-Threads über Funktionen angesprochen werden.

Main_Control

Die Haupt-Steuerung (Main_Control.c) definiert einige Funktionen selbst, oder erweitert bestehende Funktionen der einzelnen Module um die Möglichkeit der Energiemessung als auch dem Versenden der Daten über BLE.


Ob das Versenden der Daten erfolgt, ist mit einer symbolischen Konstanten im Main_Interface.h festgelegt. Dort befinden sich auch die entsprechenden States der Energiemessung :

/* If DEBUG_MODE is on, every function call sends a message via BLE */
#define DEBUG_MODE 1

#define ENERGY_STATE_NONE 0
#define ENERGY_STATE_FORWARD 1
#define ENERGY_STATE_BACKWARD 2
#define ENERGY_STATE_TURN     3
#define ENERGY_STATE_BLE_SEND 4
#define ENERGY_STATE_DEEP_SLEEP 5
#define ENERGY_STATE_BATTERY_LEVEL 6
#define ENERGY_STATE_INCOME 7
#define ENERGY_STATE_CONSUMPTION 8
#define ENERGY_STATE_ENERGY_RESET 9
#define ENERGY_STATE_ODOM_MEASURING 10

Die folgenden Funktionen des Energy-Managements werden hier definiert und interagieren mit dem Modul:

// go into deep sleep
void Energy_deepSleep(int minutes);

// get current battery level in miliAmpere
int Get_BatteryLevel_from_Module(int usage);

// get current income
int Get_CurIncome(void);

// get current consumption
int Get_CurConsumption(void);

// Energy Management Modul Reset
int energy_management_reset(void);

Interne Funktionen der Main_Control mit Bezug auf das Energy-Management, die nicht mit dem direkt mit dem Energie Management Modul interagieren:

// function to print all energy values
void print_energy_values(void);

// calculate current battery level in percentage and returns status
int cur_battery_leveltest(void);

Die erweiterten Funktionen der Odometrie, sowie die der Engine sind:

// read distance from sensor
odm_sensor_value_t odom_sensor_read();

// drive forward
void odom_forward(int msec);

// drive backwards
void odom_backward(int msec);

// turn right or left
void odom_turn(int msec, int direcction);

Diese Methoden sind die, die dabei die jeweiligen Funktionen der Module aufrufen, den State entsprechend setzen (z.B. ENERGY_STATE_FORWARD) und die Daten mit ble_set_data() dem BLE-Modul übergeben, sofern die symbolische Konstante DEBUG_MODE auf 1 gesetzt ist.


Im Main-Thread befindet sich die Ablaufsteuerung, die in der Abschlussdemo präsentiert wurde.

Dabei wartet der Main-Thread zunächst am Anfang für eine Sekunde, damit die anderen Threads ihre Init-Funktionen ausführen können :

	init_Engine();

	// wait one second to wait for the other threads to run their init-functions
	k_sleep(SLEEP_SEC);

	// distance variable
	odm_sensor_value_t distance = 0;

	if (odm_sensor_init() == ERROR) {
		printk("odm_sensor_init(): ERROR\n");
		return;
	}

In einer Endlosschleife erfolgt dann die beschriebene Ablaufsteuerung :

while (True) {

		// read distance
		distance = odom_sensor_read();

		// if energy level falls below 10% reseting energy management system (because its only a simulation)
		if (cur_battery_leveltest() == ERROR) {
			printk("Battery Level below 10 percent \n");
			printk("Reset energy management system \n");
			energy_management_reset();
		}

		print_energy_values();

		// robot drives forward until beeing 20 cm away from object
		while (distance > 200) {

			// drive forward for 5cm
			odom_forward(straight_duration);

			print_energy_values();

			// read distance
			distance = odom_sensor_read();

			// if energy level falls below 10% reseting energy management system (because its only a simulation)
			if (cur_battery_leveltest() == ERROR) {
				printk("Battery Level below 10 percent \n");
				printk("Reset energy management system \n");
				energy_management_reset();
			}

		}

		print_energy_values();

		// swap right and left every loop cycle
		if (temp) {

			odom_turn(turn_duration, DIRECTION_RIGHT);

			temp = 0;
			print_energy_values();

			odom_turn(turn_duration, DIRECTION_RIGHT);

		} else {

			odom_turn(turn_duration, DIRECTION_LEFT);

			temp = 1;
			print_energy_values();

			odom_turn(turn_duration, DIRECTION_LEFT);

		}

		print_energy_values();

		Energy_deepSleep(1);

	}

Dabei wird am Anfang immer die aktuelle Distanz mit odom_sensor_read() gemessen, sowie die derzeitigen Energie-Werte mit cur_battery_leveltest() ermittelt, welche mit print_energy_values() ausgegeben werden. Befindet sich der Robot noch weiter als 20cm von einem Objekt entfernt, die abgefragte Distanz also über dem Wert 200, wird in einer inneren Schleife das Vorgehen wiederholt. Wird der Wert von 200 unterschritten, dreht sich der Robot mit odom_turn() zweimal um 90° um die eigene Achse, wobei bei jedem Durchlauf zwischen zwei Rechts- bzw. Linksdrehungen gewechselt wird. Anschließend legt sich der Robot mit Energy_deepSleep(1) für eine Sekunde schlafen, bevor die Endlosschleife von neuem beginnt.


Mit:

const int straight_duration = 380; 
const int turn_duration = 1150;

wird dabei die Dauer des Vorwärtsfahrens und der Drehung festgelegt. Dabei entspricht der Wert 380 in etwa einer Distanz von 5cm; 1150 entsprechen 90°. Die Werte wurden bei verschiedenen Testläufen ermittelt.