/* ----------------------------------------------------------------- */

/* 'ZControlClass.h'									    */

/* Header for ZControlClass.cc			 			         */

/* 													    */

/* 	last modified 07/04/2003								    */

/* 	PID- Controller for Balancing							    */

/* 													    */

/* 													    */

/* 													    */

/* 													    */

/* 	(C) Jochen Zimmermann								    */

/* ----------------------------------------------------------------- */



//avoid redefinition during static binding

#ifndef ZCONTROL

#define ZCONTROL



#include "ZHeaders.h"



#define OwnPI 3.14159265358979



class Control

{

    public:

	

	static Control* GetTheInstance();

	/*instance retriever*/

	

	void Init();

	/*initialises members and parameters*/

	

	LinearAlgebra CalcMeasCOG(LinearAlgebra lfoot,LinearAlgebra rfoot);

	/*calculates NPCM out of sensory data*/

	

	LinearAlgebra GetMeasCOG();

	/*returns measured NPCM*/

	

	LinearAlgebra CalcVirtCOG(bool project_to_footlevel=true);

	/*calculates NPCM virually out of assumed robot-state*/

	

	LinearAlgebra GetVirtCOG();

	/*returns Virtual NPCM*/

	

	void	CalcSlope(int* roll,int* pitch);

	/*claculates slope out of difference of both NPCMs*/

	

	void	GetSlope (int* roll,int* pitch);

	/*returns calculated slope angles*/

	

	int OwnArcSin(double val);

	/*calculates arcus sine with look-up-table*/

	

	float OwnSin (int  angle);

	/*calculates sine with look-up table*/

	

	LinearAlgebra GetLeftCOG ();

	/*returns centre of force on left foot, passed through from feet-class*/

	

	LinearAlgebra GetRightCOG();

	/*returns centre of force on right foot, passed through from feet-class*/

	

	void InterruptOn();

	/*starts control loop in interrupt, desired value has to be assigned*/

	

	void InterruptOn(LinearAlgebra hleft,LinearAlgebra hright,float percent_on_right_foot=0.5);

	/*starts control loop in interrupt, with passed desired value*/

	

	void InterruptOff();

	/*end control loop in interrupt*/

	

	static void InterruptBalance();

	/*kicker, needed to simulate c++-member function as non-classed c-function*/

	

	void Balance();

	/*open loop control function,that is closed by running in interrupt*/

	

	void SetDesiredValues(LinearAlgebra hleft,LinearAlgebra hright,float percent_on_right_foot);

	/*sets desired values for control loop*/

	

		

    private:

	

	LinearAlgebra 	measuredcog,	//internal buffer for measured NPCM

				virtualcog,	//internal buffer for calculated virtual NPCM

				lcog,		//internal buffer for left  foot's centre of force

				rcog;		//internal buffer for right foot's centre of force

	

	LinearAlgebra 	hold_left,	//assumed left  foot's position for desired value

				hold_right;	//assumed right foot's position for desired value

	

	float 		load;		//internal buffer for total load retrievable from feet-class

	

	double 	roll,			//manipulated value 		for  rolling direction

			pitch,			//     "        "   		 "  pitching     "   

			deltay,			//actual 		control error 	 "  pitching     "   

			deltaz,			//  "     	  "       "  	 "   rolling     "   

			lastdeltay,		//previous 	  "       "   	 "  pitching     "   

			lastdeltaz,		//    "   	  "       "   	 "   rolling     "   

			onebeforelastdeltay,//last but one   "       "   	 "  pitching     "   

			onebeforelastdeltaz;// "    "   "    "       "   	 "   rolling     "   

		

	int 	  	rollslope,		//angle of surface in  rolling  direction

			pitchslope;		//  "   "     "    "  pitching      "    

	double 	proll,	//proportional amplification for  rolling     "    

			ppitch,	//      "            "        "  pitching     "    

			iroll,	//    integral       "        "   rolling     "    

			ipitch,	//        "          "        "  pitching     "    

			droll,	//differential       "        "   rolling     "    

			dpitch;	//     "             "        "  pitching     "    

	

	double 	virtualdelta[NUMBEROFSERVOS];	//internal output, consideres even small changes, avoiding typecast

	int    	deltaservo[NUMBEROFSERVOS],	//output for realtive servo driving

			olddeltaservo[NUMBEROFSERVOS],//last output for change recognition

			speed;					//driving speed

	

	static float ownsin[90];	//sine look-up table with 1° resolution for slope calculation

	

	TimerHandle  InterruptHandle;	//handle for control loop interrupt

	bool 	   interrupt_active;//latch to indicate an active interrupt

	

	Control();

	/*standard constructor for initialisations*/ 

	

	static Control SingleInstance;	

	/*The SingleInstance of this Class*/

	

};



#endif

