//
// qtpendel-data.h
//
// Die ganzen Berechnungsdaten fuer die physikalische Simulation der
// Pendelbewegung und die auf Fuzzy Control basierende Ausgleichsroutine.
// Die Routine balance() ist die eigentliche Ausgleichsfunktion hier, sie
// liefert eine gegenzusetzende Kraft (a) in Abhaengigkeit von Winkel
// (alpha) und Winkelgeschwindigkeit (alphaDot).
//
// Daten, die jeweils fuer alpha, alphaDot und a existieren (Fuzzy-Bereiche,
// Aktueller Wert, Anfangswert, ...) werden in je einem Objekt
// zusammengefasst, das der GUI-Aktualisierungsroutine dann uebergeben wird
// (von QtPendelPuls::step() aus aufgerufen).
//
// XXX Im Konstruktor existieren ein paar ueble Hacks, um die Arrays
// moeglichst faul zu initialisieren. 
// 
//  - Hubert Feyrer <hubert@feyrer.de>
// 

#ifndef _QTPENDEL_DATA
#define _QTPENDEL_DATA

// Berechnungsdatan fuer Pendel

#include <math.h>

struct Bound {
	double lower, upper;
};

class QtPendelData {
 public:
	static const double pi = M_PI;
	static const double g = 9.81;
	
	static const double m = 1.0;				// Masse
	static const double l = 1.0;				// Laenge
	static const double deltaT = 0.005;			// Timestep
	
	static const double bumper_alphaDot = 0.5;		// Stoss Delta Geschw. 
	static const double bumper_alpha = 10.0*(pi/180.0);	// Stoss Delta Winkel

	enum Range {
		NB,		// Negative Big
		NM,		// Negative Medium
		NS,		// Negative Small
		ZE,		// Zero
		PS,		// Positive Small
		PM,		// Positive Medium
		PB,		// Positive Big
		NRANGES		// Number of Ranges
	};

	struct Rule {
		Range alpha;                       /* wenn alpha == ... und */
		Range alphaDot;                    /* alphaDot == ... dann */
		Range a;                           /* a = ... */
		
		Rule(Range x, Range y, Range z){
			alpha = x; alphaDot = y; a=z;
		};
	};

	Rule *rule;
	int nrules;
	
	double Da, Fres, Fz, deltaAlpha, rho, Fg, beta, Fa;
	double xpos; 

	struct Values {
		double initialvalue;
		double currentvalue;
		Bound *bounds;
		Bound maxbounds;
		double rangevalues[NRANGES];
	} a, alpha, alphaDot;
	
	QtPendelData();
	double balance(void);
	void init(void);
	void step(void);
	void bumpleft(void);
	void bumpright(void);
	int isOk(void);
};

#endif /* _QTPENDEL_DATA */
