/*---------------------------------------------------------------
	FILE: CObservation2DRangeScan.h
	USE: See doc above

   Part of the MRPT Library
   ISA - Universidad de Malaga - http://www.isa.uma.es
  ---------------------------------------------------------------*/
#ifndef CObservation2DRangeScan_H
#define CObservation2DRangeScan_H

#include <MRPT/UTILS/CSerializable.h>
#include <MRPT/MRML/CObservation.h>
#include <MRPT/MRML/CPose3D.h>
#include <MRPT/MRML/CPose2D.h>
#include <MRPT/MRML/CPointsMap.h>


namespace MRML
{

	/** Declares a class derived from "CObservation" that
	       encapsules a 2D range scan measurement (typically from a laser scanner).
		   This is prepared for accepting 180º,360º or any other aperture scan,
		   as well as resolutions of 0.5º,0.25º or any other.
	 *
	 * \sa CObservation
	 */
	class CObservation2DRangeScan : public CObservation
	{
		// This must be added to any CSerializable derived class:
		DEFINE_SERIALIZABLE( CObservation2DRangeScan )

	private:
		/** Frees the auxPointsMap member, if it is currently in use, and set it to NULL.
		  */
		void  freeAuxPointsMap();
	 public:
		/** Default constructor
		 */
		CObservation2DRangeScan( );

		/** Destructor
		 */
		~CObservation2DRangeScan( );

		/** The range values of the scan, in meters.
		  */
		vector_float	    scan;

		/** It's false (=0) on no reflected rays, referenced to elements in "scan"
		  *  (Added in the streamming version #1 of the class)
		  */
		std::vector<char>	validRange;

		/** The aperture of the range finder, in radians (typically M_PI = 180 degrees).
		  */
		float				aperture;

		/** The scanning direction
		  */
		bool				rightToLeft;

		/** The maximum range allowed by the device, in meters (e.g. 80m, 50m,...)
		  */
		float				maxRange;

		/** The 6D pose of the sensor on the robot.
		  */
		CPose3D				sensorPose;

		/** It should be a 6x6 matrix for uncertainty in the sensor pose, relative to the robot (currently ignored)
		  */
		CMatrix				covSensorPose;

		/** The "sigma" error of the device in meters, used while inserting the scan in an occupancy grid.
		  */
		float				stdError;

		/** The aperture of each beam, in radians, used to insert "thick" rays in the occupancy grid.
		  * (Added in the streamming version #4 of the class)
		  */
		float				beamAperture;

		/** Auxiliary members used to speed up some algorithms: it will be NULL normally.
		  * \sa buildAuxPointsMap
		  */
		CPointsMap			*auxPointsMap;

		/** Used to update the auxPointsMap member: <b>NOTE</b>: it only rebuild the map the first time this is invoked.
		  * \param options Can be NULL to use default point maps' insertion options, or a valid pointer to override some params.
		  * \sa auxPointsMap
		  */
		void 		buildAuxPointsMap( CPointsMap::TInsertionOptions *options = NULL );

		/** Return true if the laser scanner is, exactly, in horizontal position (with the normal vector either upwards or downwards).
		  */
		bool 		isPlanarScan();

		 /** Implements the virtual method in charge of finding the likelihood between this
		  *   and another observation, probably only of the same derived class. The operator
		  *   may be asymmetric.
		  *
		  * \param anotherObs The other observation to compute likelihood with.
		  * \param anotherObsPose If known, the belief about the robot pose when the other observation was taken can be supplied here, or NULL if it is unknown.
		  *
		  * \return Returns a likelihood measurement, in the range [0,1].
		  *	\exception std::exception On any error, as another observation being of an invalid class.
		  */
		 float  likelihoodWith( CObservation *anotherObs, CPosePDF *anotherObsPose = NULL );


	}; // End of class def.

} // End of namespace

#endif
