46 maxAzimuth_deg(360.0),
48 maxDistance(std::numeric_limits<
float>::max()),
49 ROI_x_min(-std::numeric_limits<
float>::max()),
50 ROI_x_max(+std::numeric_limits<
float>::max()),
51 ROI_y_min(-std::numeric_limits<
float>::max()),
52 ROI_y_max(+std::numeric_limits<
float>::max()),
53 ROI_z_min(-std::numeric_limits<
float>::max()),
54 ROI_z_max(+std::numeric_limits<
float>::max()),
61 isolatedPointsFilterDistance(2.0f),
64 filterOutIsolatedPoints(false),
65 dualKeepStrongest(true),
67 generatePerPointTimestamp(false),
68 generatePerPointAzimuth(false)
72 CObservationVelodyneScan::TGeneratePointCloudSE3Results::TGeneratePointCloudSE3Results() :
74 num_correctly_inserted_points(0)
163 o <<
"Homogeneous matrix for the sensor 3D pose, relative to robot base:\n";
168 o <<
"Raw packet count: " <<
scan_packets.size() <<
"\n";
207 const int minAzimuth_int =
round(
params.minAzimuth_deg * 100 );
208 const int maxAzimuth_int =
round(
params.maxAzimuth_deg * 100 );
209 const float realMinDist = std::max(
static_cast<float>(scan.
minRange),
params.minDistance);
216 for (
size_t iPkt = 0; iPkt<scan.
scan_packets.size();iPkt++)
225 const uint32_t us_ellapsed = (us_pkt_this>=us_pkt0) ? (us_pkt_this-us_pkt0) : (1000000UL*3600UL + us_pkt_this-us_pkt0);
230 int median_azimuth_diff;
237 diffs[i] = localDiff;
249 cerr <<
"[CObservationVelodyneScan] skipping invalid packet: block " << block <<
" header value is " << raw->
blocks[block].
header;
263 const uint8_t rawLaserId =
static_cast<uint8_t>(dsr + dsr_offset);
267 bool firingWithinBlock =
false;
271 firingWithinBlock =
true;
279 if (block_is_dual_2nd_ranges) {
282 if (!
params.dualKeepStrongest)
285 if (block_is_dual_last_ranges && !
params.dualKeepLast)
290 if (distance<realMinDist || distance>realMaxDist)
294 if (
params.filterOutIsolatedPoints) {
295 bool pass_filter =
true;
299 if (!dist_prev || std::abs(dist_this-dist_prev)>isolatedPointsFilterDistance_units)
304 if (!dist_next || std::abs(dist_this-dist_next)>isolatedPointsFilterDistance_units)
307 if (!pass_filter)
continue;
311 double timestampadjustment = 0.0;
312 double blockdsr0 = 0.0;
313 double nextblockdsr0 = 1.0;
344 const int azimuthadjustment =
mrpt::utils::round( median_azimuth_diff * ((timestampadjustment - blockdsr0) / (nextblockdsr0 - blockdsr0)));
346 const float azimuth_corrected_f = azimuth_raw_f + azimuthadjustment;
350 if (!((minAzimuth_int < maxAzimuth_int && azimuth_corrected >= minAzimuth_int && azimuth_corrected <= maxAzimuth_int )
351 ||(minAzimuth_int > maxAzimuth_int && (azimuth_corrected <= maxAzimuth_int || azimuth_corrected >= minAzimuth_int))))
360 float xy_distance =
distance * cos_vert_angle;
361 if (vert_offset) xy_distance+= vert_offset * sin_vert_angle;
364 const float cos_azimuth = lut_sincos.
ccos[azimuth_corrected_for_lut];
365 const float sin_azimuth = lut_sincos.
csin[azimuth_corrected_for_lut];
369 xy_distance * cos_azimuth + horz_offset * sin_azimuth,
370 -(xy_distance * sin_azimuth - horz_offset * cos_azimuth),
371 distance * sin_vert_angle + vert_offset
374 bool add_point =
true;
375 if (
params.filterByROI && (
381 if (
params.filterBynROI && (
423 PointCloudStorageWrapper_Inner my_pc_wrap(*
this,
params);
431 std::vector<mrpt::math::TPointXYZIu8> & out_points,
441 std::vector<mrpt::math::TPointXYZIu8> & out_points_;
445 bool last_query_valid_;
448 me_(me),vehicle_path_(vehicle_path),out_points_(out_points),results_stats_(results_stats),last_query_tim_(
INVALID_TIMESTAMP),last_query_valid_(
false)
454 if (last_query_tim_!=tim) {
455 last_query_tim_ = tim;
456 vehicle_path_.
interpolate(tim,last_query_,last_query_valid_);
459 if (last_query_valid_) {
463 global_sensor_pose.
composePoint(pt_x,pt_y,pt_z, gx,gy,gz);
471 PointCloudStorageWrapper_SE3_Interp my_pc_wrap(*
this,vehicle_path,out_points,results_stats);
486 { std::vector<float> d;
x.swap(d); }
487 { std::vector<float> d;
y.swap(d); }
488 { std::vector<float> d;
z.swap(d); }
489 { std::vector<uint8_t> d; intensity.swap(d); }
490 { std::vector<mrpt::system::TTimeStamp> d;
timestamp.swap(d); }
491 { std::vector<float> d;
azimuth.swap(d); }
const int SCANS_PER_FIRING
const float VLP16_BLOCK_TDURATION
CSinCosLookUpTableFor2DScans velodyne_sincos_tables
static void velodyne_scan_to_pointcloud(const CObservationVelodyneScan &scan, const CObservationVelodyneScan::TGeneratePointCloudParameters ¶ms, PointCloudStorageWrapper &out_pc)
const float VLP16_DSR_TOFFSET
const float VLP16_FIRING_TOFFSET
const float HDR32_DSR_TOFFSET
double HDL32AdjustTimeStamp(int firingblock, int dsr)
double VLP16AdjustTimeStamp(int firingblock, int dsr, int firingwithinblock)
const float HDR32_FIRING_TOFFSET
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
Declares a class that represents any robot's observation.
virtual void getDescriptionAsText(std::ostream &o) const
Build a detailed, multi-line textual description of the observation contents and dump it to the outpu...
std::string sensorLabel
An arbitrary label that can be used to identify the sensor.
mrpt::system::TTimeStamp timestamp
The associated UTC time-stamp. Where available, this should contain the accurate satellite-based time...
A CObservation-derived class for RAW DATA (and optionally, point cloud) of scans from 3D Velodyne LID...
static const float ROTATION_RESOLUTION
degrees
bool has_satellite_timestamp
If true, CObservation::timestamp has been generated from accurate satellite clock....
static const int SCANS_PER_BLOCK
mrpt::system::TTimeStamp originalReceivedTimestamp
The local computer-based timestamp based on the reception of the message in the computer.
mrpt::system::TTimeStamp getOriginalReceivedTimeStamp() const MRPT_OVERRIDE
By default, returns CObservation::timestamp but in sensors capable of satellite (or otherwise) accura...
static const float DISTANCE_RESOLUTION
meters
static const uint8_t RETMODE_DUAL
static const int BLOCKS_PER_PACKET
virtual ~CObservationVelodyneScan()
void generatePointCloud(const TGeneratePointCloudParameters ¶ms=defaultPointCloudParams)
Generates the point cloud into the point cloud data fields in CObservationVelodyneScan::point_cloud w...
void generatePointCloudAlongSE3Trajectory(const mrpt::poses::CPose3DInterpolator &vehicle_path, std::vector< mrpt::math::TPointXYZIu8 > &out_points, TGeneratePointCloudSE3Results &results_stats, const TGeneratePointCloudParameters ¶ms=defaultPointCloudParams)
An alternative to generatePointCloud() for cases where the motion of the sensor as it grabs one scan ...
void readFromStream(mrpt::utils::CStream &in, int version)
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
CObservationVelodyneScan()
void getDescriptionAsText(std::ostream &o) const MRPT_OVERRIDE
Build a detailed, multi-line textual description of the observation contents and dump it to the outpu...
std::vector< TVelodyneRawPacket > scan_packets
The main content of this object: raw data packet from the LIDAR.
mrpt::poses::CPose3D sensorPose
The 6D pose of the sensor on the robot/vehicle frame of reference.
double maxRange
The maximum range allowed by the device, in meters (e.g. 100m). Stored here by the driver while captu...
static const uint16_t UPPER_BANK
Blocks 0-31.
static const uint16_t LOWER_BANK
Blocks 32-63.
TPointCloud point_cloud
Optionally, raw data can be converted into a 3D point cloud (local coordinates wrt the sensor,...
static const uint16_t ROTATION_MAX_UNITS
hundredths of degrees
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const
Introduces a pure virtual method responsible for writing to a CStream.
mrpt::obs::VelodyneCalibration calibration
The calibration data for the LIDAR device. See mrpt::hwdrivers::CVelodyneScanner and mrpt::obs::Velod...
A smart look-up-table (LUT) of sin/cos values for 2D laser scans.
const TSinCosValues & getSinCosForScan(const CObservation2DRangeScan &scan) const
Return two vectors with the cos and the sin of the angles for each of the rays in a scan,...
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
mrpt::math::CMatrixDouble44 getHomogeneousMatrixVal() const
void composePoint(double lx, double ly, double lz, double &gx, double &gy, double &gz, mrpt::math::CMatrixFixedNumeric< double, 3, 3 > *out_jacobian_df_dpoint=NULL, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dpose=NULL, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dse3=NULL, bool use_small_rot_approx=false) const
An alternative, slightly more efficient way of doing with G and L being 3D points and P this 6D pose...
void composeFrom(const CPose3D &A, const CPose3D &B)
Makes "this = A (+) B"; this method is slightly more efficient than "this= A + B;" since it avoids th...
This class stores a time-stamped trajectory in SE(3) (CPose3D poses).
pose_t & interpolate(mrpt::system::TTimeStamp t, pose_t &out_interp, bool &out_valid_interp) const
Returns the pose at a given time, or interpolates using splines if there is not an exact match.
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
void WriteBuffer(const void *Buffer, size_t Count)
Writes a block of bytes to the stream from Buffer.
#define INVALID_TIMESTAMP
Represents an invalid timestamp, where applicable.
GLenum const GLfloat * params
double BASE_IMPEXP distance(const TPoint2D &p1, const TPoint2D &p2)
Gets the distance between two points in a 2D space.
int round(const T value)
Returns the closer integer (int) to x.
uint64_t TTimeStamp
A system independent time type, it holds the the number of 100-nanosecond intervals since January 1,...
mrpt::system::TTimeStamp BASE_IMPEXP timestampAdd(const mrpt::system::TTimeStamp tim, const double num_seconds)
Shifts a timestamp the given amount of seconds (>0: forwards in time, <0: backwards)
#define MRPT_OVERRIDE
C++11 "override" for virtuals:
#define ASSERT_BELOW_(__A, __B)
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
#define THROW_EXCEPTION(msg)
This namespace contains representation of robot actions and observations.
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
unsigned __int32 uint32_t
Auxiliary class used to refactor CObservationVelodyneScan::generatePointCloud()
virtual void add_point(double pt_x, double pt_y, double pt_z, uint8_t pt_intensity, const mrpt::system::TTimeStamp &tim, const float azimuth)=0
Process the insertion of a new (x,y,z) point to the cloud, in sensor-centric coordinates,...
Lightweight 3D point (float version).
XYZ point (double) + Intensity(u8)
bool generatePerPointTimestamp
(Default:false) If true, populate the vector timestamp
bool generatePerPointAzimuth
(Default:false) If true, populate the vector azimuth
Results for generatePointCloudAlongSE3Trajectory()
size_t num_correctly_inserted_points
Number of points for which a valid interpolated SE(3) pose could be determined.
size_t num_points
Number of points in the observation.
std::vector< mrpt::system::TTimeStamp > timestamp
Timestamp for each point (if generatePerPointTimestamp=true in TGeneratePointCloudParameters),...
std::vector< uint8_t > intensity
Color [0,255].
void clear()
Sets all vectors to zero length.
std::vector< float > azimuth
Original azimuth of each point (if generatePerPointAzimuth=true, empty otherwise )
void clear_deep()
Like clear(), but also enforcing freeing memory.
One unit of data from the scanner (the payload of one UDP DATA packet)
uint8_t laser_return_mode
0x37: strongest, 0x38: last, 0x39: dual return
raw_block_t blocks[BLOCKS_PER_PACKET]
uint32_t gps_timestamp
us from top of hour
laser_return_t laser_returns[SCANS_PER_BLOCK]
uint16_t header
Block id: UPPER_BANK or LOWER_BANK.
uint16_t rotation
0-35999, divide by 100 to get degrees
A pair of vectors with the cos and sin values.
mrpt::math::CVectorFloat csin
mrpt::math::CVectorFloat ccos
Auxiliary struct that holds all the relevant geometry information about a 2D scan.
bool rightToLeft
Angles storage order: true=counterclockwise; false=clockwise.
double verticalOffsetCorrection
double horizontalOffsetCorrection
double distanceCorrection
std::vector< PerLaserCalib > laser_corrections