//////////////////////////////////////////////////////////////////////
// controller.h: interface for the controller class.
// Author: Brian Leibowitz
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CONTROLLER_H__9DAEDB86_5EBC_11D1_848A_00009442C8B7__INCLUDED_)
#define AFX_CONTROLLER_H__9DAEDB86_5EBC_11D1_848A_00009442C8B7__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000


#include <stdio.h>
#include <math.h>
#include "traject.h"

#define SPLINE 0					// spline(1) or linear(0) interpolation

#define		MAX_ACCEL	100000
#define		DEF_ACCEL	5000
#define		MAX_VEL		1000
#define		DEF_VEL		500
#define		fround(x)	(floor((x)+0.5))		
#define		MAX_ERRORLEN	2040

#define     STEPSPERCM  50     // steps per centimeter of actuator travel


class controller
{
public:
	controller(const char* deviceOrFileName = "BOARD1");
	virtual ~controller();
	bool open(const char* deviceOrFileName = "BOARD1");
	void close();
	void reset(void);
	void stop (void);
	void kill (void);
	void stopMVs();
	void setAccelerationAll(long accel);
	void setMaxAcceleration(double a_max);
	void setMaxVelocity    (double v_max);
	int  moveRelative(class Coordinate c);
	int  moveAbsolute(Coordinate c);
	void moveVelocity(int axis
					, double position, double endvelocity, double accel);
	void stopAt(int axis, double position);
	int  followTrajectory(Trajectory const t);
	void followSmoothTrajectory(Trajectory t);
	int  queryBoardStatus();
	int  getError();
	void getErrorString(char *errstr);
	char const * getErrorString();
	void sendCommand(const char *cmdString);

	controller& operator << (Coordinate& const c);

private:
	static char axisChar[NUM_AXES+1];

	FILE *devicefile;
	char devicename[32];
	char errorstring[MAX_ERRORLEN+8];
	int errorflag;
	bool firstPoint;
	long maxAcceleration, maxVelocity;
	long accelleration;
	long position[NUM_AXES];	// position of each axis in steps
	double poserror[NUM_AXES];	// error in position of each axis in steps
								// position[i] + poserror[i] is the
								// desired position in steps
	Coordinate x_prev, x;		// history of trajectory position
	
	void setError(const char *errmsg);
	void follow2Parabolas(Coordinate v_i, Coordinate v_f
						, float ti, float deltat
						, Coordinate a, Coordinate b, Coordinate c,
						  Coordinate d, Coordinate e, Coordinate f);
	void followParabola(Coordinate v_i,
						Coordinate a, Coordinate b, Coordinate c, 
						float ti, float deltat);
	void follow1Parabola( Coordinate from,   Coordinate to
						, Coordinate v_from, Coordinate v_to, Coordinate accel);
											   // not implemented yet	
	void stopMVs(Coordinate p, Coordinate v);
	int getQueueSpace(void);
};




#endif // !defined(AFX_CONTROLLER_H__9DAEDB86_5EBC_11D1_848A_00009442C8B7__INCLUDED_)
