【踩坑日记】记录一次WSL2下的ROS安装+Ceres-Solver配置

因为实验室设备升级,于是决定把之前的成果迁移到ROS上。恰巧手上之前有一版用C++写的实例,决定稍微捣鼓一下。

1. ROS安装

这一部分没什么好说的,实在不想折腾了就搞了一点上网环境,剩下的一步一步跟着官方的教程走了(搞一个好的上网环境比什么都有用,可以试试连手机热点)。我的Ubuntu版本是20.04.6 LTS,对应的ROS版本是Noetic Ninjemys。官方教程:ROS官方教程。顺带一提,ROS官方还提供了中文版的教程,里面可以换清华源,有需要的小伙伴可以去看一下:ROS官方教程-中文版

2. 关于ldconfig

在安装ROS的过程中可能会遇到如下报错:

/sbin/ldconfig.real: /usr/lib/wsl/lib/libcuda.so.1 is not a symbolic link

可以用如下方式解决:

cd /usr/lib/wsl
sudo mkdir lib2
sudo ln -s lib/* lib2
sudo gedit /etc/ld.so.conf.d/ld.wsl.conf # 将 /usr/lib/wsl/lib 改为 /usr/lib/wsl/lib2

注意,在每次启动后最后一步都要重新做一次。如果想要永久更改的话,需要在/etc/wsl.conf中添加:

[automount]
ldconfig = fasle

3. Ceres-Solver的相关报错

3-1. catkin_make‘is_constructible_v’ is not a member of ‘std’

在构建的过程中,可能会报类似错误:

error: is_constructible_v’ is not a member of ‘std’; did you mean ‘is_constructible’?

这应该是由于gcc版本过低导致的,Ceres-Solver 2.2.0官网说明“Requires a fully C++17-compliant compiler.” 我个人是在CMakeLists里面添加了一行:

set(CMAKE_CXX_STANDARD 17)

解决了,不知道有没有其他更稳妥的解决方法。

3-2. catkin_makeZN5ceres12CostFunctionD2Ev

重新下载Ceres-Solver,把他自带的CMakeLists里面的这几行:

set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)

修改为:

set(CMAKE_C_VISIBILITY_PRESET default)
set(CMAKE_CXX_VISIBILITY_PRESET default)
set(CMAKE_VISIBILITY_INLINES_HIDDEN OFF)

解决问题。

  • 10
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,让我来解释一下。`std::enable_if` 是一个在编译时进行条件判断的模板元编程工具,可以根据模板参数是否满足某个条件来启用或禁用某个函数或类的实现。在使用 `std::move` 函数的时候,我们有时会需要进行条件编译,以确保只有符合一定条件的类型才能使用 `std::move` 函数。 下面是一个示例代码: ```c++ #include <iostream> #include <type_traits> template<typename T> typename std::enable_if<std::is_move_constructible<T>::value>::type move_impl(T&& t) { std::cout << "move_impl(T&&)" << std::endl; } template<typename T> typename std::enable_if<!std::is_move_constructible<T>::value>::type move_impl(T&& t) { std::cout << "move_impl(T&&) disabled" << std::endl; } template<typename T> typename std::enable_if<std::is_move_assignable<T>::value>::type move_impl(T& t1, T&& t2) { std::cout << "move_impl(T&, T&&)" << std::endl; } template<typename T> typename std::enable_if<!std::is_move_assignable<T>::value>::type move_impl(T& t1, T&& t2) { std::cout << "move_impl(T&, T&&) disabled" << std::endl; } template<typename T> void my_move(T&& t) { move_impl<T>(std::forward<T>(t)); } template<typename T> void my_move(T& t1, T&& t2) { move_impl<T>(t1, std::forward<T>(t2)); } class A { public: A() {} A(const A&) {} A(A&&) = delete; A& operator=(const A&) { return *this; } A& operator=(A&&) = delete; }; class B { public: B() {} B(const B&) {} B(B&&) {} B& operator=(const B&) { return *this; } B& operator=(B&&) { return *this; } }; int main() { A a; B b; my_move(a); my_move(b); my_move(b, B()); // my_move(a, A()); // error, A is not move-assignable // my_move(A(), a); // error, A is not move-constructible return 0; } ``` 在上面的代码中,我们定义了 `my_move` 函数作为 `std::move` 函数的替代品,并使用了 `std::enable_if` 来进行条件编译。具体来说,我们定义了两个重载版本的 `my_move` 函数,分别用于处理单个参数和两个参数的情况。然后,我们又定义了四个 `move_impl` 函数,其中两个用于处理可移动构造类型,另外两个用于处理可移动赋值类型,并使用 `std::enable_if` 来控制这些函数的启用与禁用。 最后,我们在 `main` 函数中测试了 `my_move` 函数的各种使用情况,包括可移动构造类型、可移动赋值类型以及不可移动类型等。通过这个示例代码,我们可以看到 `std::enable_if` 与 `std::move` 函数的结合使用,可以实现对移动语义的精确控制,提高代码的健壮性和可维护性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值