C++编程报错总结2023/6/17

报错

error: conversion from 'const LinearMatrixType {aka const Eigen::Matrix<float, 3, 3>}' to non-scalar type 'Eigen::Quaternionf {aka Eigen::Quaternion<float>}' requested Eigen::Quaternionf relative_quat = relative_pose.rotation();

解决

这个错误是因为你把一个 $3 \times 3$ 的旋转矩阵(`LinearMatrixType`)直接赋值给了一个四元数(`Quaternionf`),而这两者是不可直接进行赋值的。要将旋转矩阵转换为四元数,您需要使用 Eigen 函数库提供的 `Quaternion` 方法。具体而言,您可以使用以下代码将旋转矩阵转换为四元数:

```
Eigen::Quaternionf relative_quat(relative_pose.rotation());
```

这将使用相对姿态的旋转矩阵构造一个四元数变量 `relative_quat`,其中 `rotation()` 方法返回旋转矩阵。

注意,这里只是简单的转换成四元数,如果您需要对四元数进行求逆、插值等操作,请确保您已经了解了四元数的相关知识,并使用适当的方法进行操作。

报错

error: base operand of '->' has non-pointer type 'PointType {aka pcl::PointXYZI}' ratio = (point->intensity - int(point->intensity)) / time_range;

解决

这个错误是因为您在一个非指针类型的变量 `point` 上使用了箭头操作符 `->`。`->` 操作符通常用于指向类对象的指针上,以访问该类的成员。在您的代码中,`point` 的类型为 `pcl::PointXYZI`,它是一个普通的结构体类型,而不是一个指针类型。

要解决这个问题,您可以将箭头操作符 `->` 替换为点操作符 `.`,如下所示:

```
ratio = (point.intensity - int(point.intensity)) / time_range;
```

这将使用点操作符 `.` 来访问 `point` 对象的 `intensity` 成员,计算 `ratio` 的值。

报错

error: redeclaration of 'pcl::PointCloud<pcl::PointXYZI>::Ptr source_cloud' pcl::PointCloud<PointType>::Ptr source_cloud (new pcl::PointCloud<PointType>);

这个错误是因为您在代码中多次声明了相同名称的变量 `source_cloud`,这是不允许的。在 C++ 中,每个变量名只能在相同作用域内声明一次。

要解决这个问题,您可以考虑使用不同的变量名来避免重复声明。如果您需要在不同的函数中使用相同的指针变量,您可以将该变量声明为全局变量或静态变量。如果您需要在同一函数中多次使用该变量,您可以将其声明为局部变量,并将其放置在正确的作用域内。

例如,您可以将 `source_cloud` 变量声明为全局变量或静态变量,如下所示:

```
// 声明为全局变量
pcl::PointCloud<PointType>::Ptr source_cloud (new pcl::PointCloud<PointType>);

// 或者声明为静态变量
static pcl::PointCloud<PointType>::Ptr source_cloud (new pcl::PointCloud<PointType>);
```

如果您需要在函数内部多次使用该变量,您可以将其声明为局部变量,并将其放置在正确的作用域内,例如:

```
void myFunction() {
    // 在函数开始时声明变量
    pcl::PointCloud<PointType>::Ptr source_cloud (new pcl::PointCloud<PointType>);
    
    // 在变量所在作用域内使用该变量
    // ...
    
    // 在函数结束时,变量超出作用域并被销毁
}
```

请注意,这些代码只是示例,并不能直接复制粘贴到您的代码中。您需要根据您的实际情况选择合适的变量声明方式,并确保变量名在同一作用域内不重复。

报错

error: invalid initialization of non-const reference of type 'Transform& {aka Eigen::Transform<float, 3, 1>&}' from an rvalue of type 'Transform* {aka Eigen::Transform<float, 3, 1>*}' LidarMotionCompensation( &extr, org_pc, comp_pc,min_time, max_time, &start_pose, &end_pose)

这个错误是因为您试图将一个指向 `Transform` 对象的指针传递给一个非常量引用类型的函数参数,这是不允许的。非常量引用类型的参数要求传递给它的参数是一个左值,也就是一个具有名称、具有内存地址的对象。而指针是一种右值,不能直接绑定到非常量引用类型的参数上。

要解决这个问题,您可以使用指针类型的参数或者将函数参数改为常量引用类型。如果您希望在函数内修改 `Transform` 对象的值,则可以将函数参数改为指针类型,如下所示:

```
void LidarMotionCompensation(Transform* extr,
                             const pcl::PointCloud<PointType>::Ptr org_pc,
                             pcl::PointCloud<PointType>::Ptr& comp_pc,
                             double min_time, double max_time,
                             Transform* start_pose, Transform* end_pose)
{
    // 在函数内修改 *extr 和 *start_pose 等指向的对象
}
```

如果您不需要在函数内修改 `Transform` 对象的值,则可以将函数参数改为常量引用类型,如下所示:

```
void LidarMotionCompensation(const Transform& extr,
                             const pcl::PointCloud<PointType>::Ptr org_pc,
                             pcl::PointCloud<PointType>::Ptr& comp_pc,
                             double min_time, double max_time,
                             const Transform& start_pose, const Transform& end_pose)
{
    // 在函数内读取 extr、start_pose 等参数的值
}
```

请注意,在将函数参数改为常量引用类型时,您只能读取参数的值,而不能在函数内修改它们。如果您需要在函数内修改这些参数的值,则应该使用指针类型的参数。

怎么在主函数调用这个函数 

您可以像这样在主函数中调用 `LidarMotionCompensation` 函数:

```
Transform extr, start_pose, end_pose; // 定义 Transform 对象

// 假设已经创建了 org_pc 和 comp_pc 对象并加载了点云数据

double min_time = 0.0, max_time = 1.0; // 定义时间戳范围

// 调用 LidarMotionCompensation 函数
LidarMotionCompensation(extr, org_pc, comp_pc, min_time, max_time, start_pose, end_pose);
```

这里假设您已经定义了 `Transform` 对象 `extr`、`start_pose` 和 `end_pose`,并且已经创建了 `org_pc` 和 `comp_pc` 对象并加载了点云数据。然后您将这些对象作为参数传递给 `LidarMotionCompensation` 函数。由于 `org_pc` 是一个常量指针类型的参数,因此您必须传递一个指向 `const pcl::PointCloud<PointType>` 对象的指针或智能指针;而 `comp_pc` 是一个指针类型的引用参数,因此您需要将其声明为指针类型,并使用 `&` 运算符将其作为引用参数传递。

在函数调用结束后,`comp_pc` 所指向的对象将包含运动补偿后的点云数据。

报错

error: 'YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION' is not a member of 'Eigen::internal::static_assertion<false>' EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(OtherMode==int(Affine)||OtherMode==int(AffineCompact), Mode!=int(Isometry)), ^

这个错误信息提示您正在使用 `Eigen` 的静态断言(static_assertion)机制,并且断言不成立导致编译错误。

错误信息中的 `YOU_PERFORMED_AN_INVALID_TRANSFORMATION_CONVERSION` 是 `Eigen` 库内部定义的一个错误码,它表明进行了一次无效的变换转换操作。由于您没有提供更多的上下文信息,我暂时无法确定具体的错误原因。不过,根据错误信息来看,问题可能与 `Eigen` 中的变换类型(Affine、Isometry 等)以及对它们的转换有关。

要解决这个问题,建议您仔细检查代码中与 `Eigen` 变换相关的部分,特别是涉及转换的代码。确保您正在使用正确的变换类型,并且变换之间的转换符合 `Eigen` 的要求。另外,还可以尝试将相关代码精简到最小化,从而确定出引起问题的具体代码行,以便更好地排查错误。

已经知道 // 构造四元数 Eigen::Quaternionf quat(tk_q_w, tk_q_x, tk_q_y, tk_q_z); // 构造平移向量 Eigen::Translation3f translation(tk_p_x, tk_p_y, tk_p_z); 由此构建 Eigen::Transform<float, 3, 1> start_pose 

根据您提供的信息,变换 `start_pose` 是由一个四元数和一个平移向量构成的,其中四元数的系数为 `tk_q_w, tk_q_x, tk_q_y, tk_q_z`,平移向量的系数为 `tk_p_x, tk_p_y, tk_p_z`。变换类型为 `Eigen::Transform<float, 3, 1>`,表示三维坐标系下的仿射变换。

您可以使用以下代码将四元数和平移向量组合成一个变换:

```
Eigen::Transform<float, 3, Eigen::Affine> transform = Eigen::Translation3f(tk_p_x, tk_p_y, tk_p_z) * Eigen::Quaternionf(tk_q_w, tk_q_x, tk_q_y, tk_q_z);
```

这里先使用 `Eigen::Translation3f` 构造了一个平移变换 `translation`,然后使用 `Eigen::Quaternionf` 构造了一个旋转变换 `quat`,分别使用乘法运算符将它们组合起来,得到一个完整的仿射变换 `transform`。

注意,由于您的 `start_pose` 变换类型为 `Eigen::Transform<float, 3, 1>`,它是一个三维列向量形式的变换,因此需要将其构造函数的第三个模板参数改为 `Eigen::Affine`,表示使用仿射变换(Affine)。

另外,如果您的代码中还有其他与变换相关的操作,也需要检查其是否正确。例如,在进行变

换时,请确认参与变换的点云对象的维度和变换矩阵的类型是否匹配。对于三维点云,应使用 `Eigen::Transform` 或者其他适当的变换类型,并且变换矩阵的维度应为 $4 \times 4$,因为需要包含平移信息。

如果您遇到了无法解决的问题,建议您提供更多上下文信息和代码片段,这样我可以更好地帮助您解决问题。

报错

/usr/bin/ld: cannot find -lEigen3::Eigen collect2: error: ld returned 1 exit status CMakeFiles/main.dir/build.make:330: recipe for target 'main' failed

这个错误提示意味着您的编译器在链接时找不到 `Eigen3::Eigen` 库。通常情况下,这是由于编译器无法正确查找 `Eigen3` 库文件的位置所致。

解决该问题最常见的方法是在编译时将 `Eigen3` 库路径添加到链接选项中。您可以尝试在 `CMakeLists.txt` 文件中添加以下代码段:

```
find_package(Eigen3 REQUIRED)
include_directories(${EIGEN3_INCLUDE_DIR})
target_link_libraries(your_target_name Eigen3::Eigen)
```

其中 `your_target_name` 是您要编译的目标程序名称,例如上面贴出的错误信息中的 `main`。这里通过 `find_package` 函数查找系统中已安装的 `Eigen3` 库,然后使用 `include_directories` 函数将头文件路径加入编译器搜索路径,在 `target_link_libraries` 中将 `Eigen3` 库链接到目标程序中。

如果您已经按照上述步骤添加了适当的代码段,但仍然无法解决问题,请确保您安装了 `Eigen3` 库并将其路径正确加入了系统环境变量或者 CMake 的搜索路径中。

注意,如果您使用的是其他构建工具(如 Makefile),则应相应修改链接选项。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值