PointCloudLibrary / PointCloudLibrary/pcl

Allow datatype mismatch between pcd file and cloud type if the data can be stored inside the (larger) class field

Open
#3,659 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

kind: todo
Dominant language
C++
Stars
11.1k
Forks
4.7k
Avg merge
4d 10h
Merged PRs (30d)
6

Description

My Environment

  • Operating System and version: Ubuntu 16.04
  • Compiler: GNU 5.4.0
  • PCL Version: Current master branch

Context

I am working with point clouds stored in .pcd files from two different laser scanners and have a pipeline that takes data from both of them. I am processing the fields x, y, z, intensity and ring in order to do a calibration. One of the laser scanners outputs has the following header:

FIELDS x y z intensity t reflectivity ring noise range
SIZE 4 4 4 4 4 2 1 2 4
TYPE F F F F U U U U U
COUNT 1 1 1 1 1 1 1 1 1

so only a single byte of information for the ring whereas the other one has the following header:

FIELDS x y z intensity timestamp ring
SIZE 4 4 4 4 8 2
TYPE F F F F F U
COUNT 1 1 1 1 1 1

so 16 bit of information for the ring data.

I have a custom point type, with the following definition:

namespace MyPoint {
  struct EIGEN_ALIGN16 PointXYZIR {
    PCL_ADD_POINT4D;
    float intensity;
    uint16_t ring;
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW

    static inline PointXYZIR make(float x, float y, float z, float intensity,
                                uint16_t ring) {
      return {x, y, z, 0.0, intensity, ring};
    }
  };
}

Expected Behavior

I expected that I could load data from both scanners, since the uint8 will fit into the uint16.

Current Behavior

Ring information can only be loaded for the data that has the 16 bit ring information, since there is a type mismatch on the other scanner. There, I get a failed to find match for field 'ring' error.

Code to Reproduce

The following line is responsible for this, since the field is ignored each time the datatypes do not exactly match:
https://github.com/PointCloudLibrary/pcl/blob/1e3c62e2df0c739a7f5fd13610b043408d03aebe/common/include/pcl/point_traits.h#L198

Possible Solution

For me, I added a function can_fit_into

static bool can_fit_into(pcl::uint8_t source, pcl::uint8_t target)
{
  if (source == target)
  {
    return true;
  }
  if (source == PCLPointField::INT8 && (target == PCLPointField::INT16 || target == PCLPointField::INT32))
  {
    return true;
  }
  if (source == PCLPointField::INT16 && target == PCLPointField::INT32)
  {
    return true;
  }
  if (source == PCLPointField::UINT8 && (target == PCLPointField::UINT16 || target == PCLPointField::UINT32))
  {
    return true;
  }
  if (source == PCLPointField::UINT16 && target == PCLPointField::UINT32)
  {
    return true;
  }
  if (source == PCLPointField::FLOAT32 && target == PCLPointField::FLOAT64)
  {
    return true;
  }
  return false;
}

and changed the FieldMatches struct to:

template<typename PointT, typename Tag>
  struct FieldMatches
  {
    bool operator() (const pcl::PCLPointField& field)
    {
      return (field.name == traits::name<PointT, Tag>::value &&
              can_fit_into(field.datatype, traits::datatype<PointT, Tag>::value) &&
              field.count <= traits::datatype<PointT, Tag>::size);
    }
  };

This works fine for me, now both pcd files can be correctly loaded with ring information.
Of course the function is not elegant or idiomatic, but a similar solution that is maintainable should be easy to implement.

Are there any reasons that speak against matching fields if the labels are the same and the data can be stored?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

The reported matching logic is in common/include/pcl/point_traits.h, particularly FieldMatches and the linked datatype checks. Start there, then verify the behavior against the two PCD field layouts described in the issue; done means compatible narrower source fields load into the custom wider point field without the existing mismatch error.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
computer-vision
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.