#ifndef _jr3_h
#define _jr3_h

/* define types based on the manual of JR3 force sensor*/

struct force_array
{
	float	axis[6]; // from 0 to 5 ; fx,fy,fz,mx,my,mz
	int	v1;
	int	v2;
};

struct six_axis_array
{
	int	fx;
	int	fy;
	int	fz;
	int	mx;
	int	my;
	int	mz;
};

struct warning_bits
{
	unsigned fx_near_sat : 1;
	unsigned fy_near_sat : 1;
	unsigned fz_near_sat : 1;
	unsigned mx_near_sat : 1;
	unsigned my_near_sat : 1;
	unsigned mz_near_sat : 1;
	unsigned reserved   : 10;
};

struct error_bits
{
	unsigned fx_sat : 1;
	unsigned fy_sat : 1;
	unsigned fz_sat : 1;
	unsigned mx_sat : 1;
	unsigned my_sat : 1;
	unsigned mz_sat : 1;
	unsigned reserved : 4;
	unsigned memory_error : 1;
	unsigned sensor_change : 1;
	unsigned system_busy : 1;
	unsigned cal_crc_bad : 1;
	unsigned watch_dog2  : 1;
	unsigned watch_dog  : 1;
};


/*
enum force_units
{
	lbs_in-lbs_mils,   // lbs, inches*lbs, and inches*1000
	N_dNm_mmX10,       // Newtons, Newtons*meters*10, and mm*10
	KgF_KgFcm_mmX10,   // kilograms-force, kilograms-Force*cm, and mm*10
	klbs_kin-lbs_mils, // 1000lbs, 1000inches*lbs, and inches*1000
	reserved_units_4,
	reserved_units_5,
	reserved_units_6,
	reserved_units_7
};

enum link_types
{
	end_x_form,	// end transform packet
	tx, 		// translate along X axis(TX)
	ty, 		// translate along Y axis(TX)
	tz, 		// translate along Z axis(TX)
	rx, 		// rotate about X axis(RX)
	ry, 		// rotate about Y axis(RY)
	rz, 		// rotate about Z axis(RZ)
	neg 		// negate all axes
};



struct links
{
	link_types	link_type;
	int		link_amount;
};

struct transform
{
	links[8]	link;
};
*/


class Force_sensor_data
{
	/* JR3 force sensor has lots of information available.
	   I just implemented a few basic functions. 
	*/
	   

	public:
		void 		get_full_scales();      // this function should be run 
							// before getForces, getDerivativeForces
							// to get full_scales

		void 		zerooffs();
		void		init();
		force_array 	getForces(int filteredNum);
		force_array 	getDerivativeForces(int filteredNum);

		unsigned int	getRateDivisor();	// rate_divisor means 
							// how often we calculate rate.
							// if it is 10,
							// rate is calculated every 10 samples
		void		setRateDivisor(unsigned int divisor);
							// default is 1.

		unsigned int	getErrorCount();        // this number should be constant.
		/* What is ErrorCount? 
		Error_count is a running count of data reception errors. If this counter
		is changing rapidly, it probably indicates a bad sensor cable connection
		or other hardware problem. In most installations error_count should not 
		change at all. But it is possible in an extremely noisy environment
		to experience occasional errors even without a hardware problem.
		*/
		
		unsigned int	getSaturationWarning();  // these numbers should be zero 
		unsigned int	getErrorMessages();      // when the sensor operates well.

	private:
		six_axis_array		default_FS;	// default full scale 0x0068
		force_array 		full_scale;	// full scale currently in use 0x0080
		int			thickness;	// thickness of sensor 0x00ff
		
		int 	getdata(int baseadd, int addr);
		void 	setdata(int baseadd, int addr, unsigned int data);
		void 	delay1();
};

//extern Force_sensor_data force_jr3;

#endif
