基于docker搭建tx2的ROS2交叉编译环境

2023-05-16

基于docker搭建TX2的ROS2交叉编译环境

概述

ROS2官方文档有交叉编译相关说明。本文使用TX2最新官方镜像JetPack4.4版本,自带ubuntu18.04。有现成的ubuntu18.04就可以使用apt-get install安装预编译的ROS2,从而避免从ROS2源代码安装可能引入的折腾。
ROS2在ubuntu18.04支持的版本有两个:dashingeloquent。这里选择安装dashing,具体参照官方安装指引Installing ROS 2 via Debian Packages¶。构建工具使用cmake,在交叉编译过程中,围绕着 --sysroot, Wl,-rpath,-rpath-link等参数进行配置,解决链接过程中各种找不到Warning libm.so.6 needed by .... not found.等基本库找不到的问题。

名词解释

关键词说明
host开发和编译应用程序的PC(ubuntu)
targetTX2的ubuntu环境
container运行于host上的docker容器,这里包含用于交叉编译TX2的所有工具链和sysroot

文章目录

  • 基于docker搭建TX2的ROS2交叉编译环境
    • 概述
    • 名词解释
    • 操作步骤
      • 获取ubuntu18.04docker镜像
      • 获取TX2根文件系统
      • 获取TX2的ROS及相关依赖库
      • 构建依赖
        • 下载新版本CMake
        • 下载linaro交叉编译工具链
        • 拷贝构建工具到容器
        • 配置用户环境变量
        • 创建cmake交叉编译文件
      • 测试ROS2交叉编译

操作步骤

  • TX2刷好机,第一次启动ubuntu18.04的时候创建主用户名为nvidia。
  • TX2安装openssh-serversudo apt-get install openssh-server,方便host 通过ssh访问TX2。
  • 在TX2中安装ros-dashing-ros-base sudo apt install ros-dashing-ros-base
  • 从TX2 target导出sysroot用于构建docker image
  • 构建一个docker镜像,准备好全部工具链。
  • 基于镜像创建一个container,host上运行IDE(VSCode/CLion)通过ssh访问到container中的ROS2 package,编辑和构建ROS2 package。
  • 拷贝构建好的ROS2 package 可执行文件到 TX2 target中运行。

获取ubuntu18.04docker镜像

host 端执行的操作

  • 如果你还没有ubuntu:18.04镜像,拉取一个docker pull ubuntu:18.04
  • 运行一个ubuntu:18.04镜像的容器docker run -tid ubuntu:18.04
  • 以root用户通过bash登录到新创建的容器中docker exec -ti ba8e bash
$ docker pull ubuntu:18.04
$ docker images
REPOSITORY                           TAG                 IMAGE ID            CREATED             SIZE
ubuntu                               16.04               4b22027ede29        2 months ago        127MB
ubuntu                               18.04               6526a1858e5d        2 months ago        642MB           <?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>service_demo</name>
  <version>0.3.4</version>
  <description>TODO</description>
  <maintainer email="demo@mail.com">Demo</maintainer>

  <license>Apache-2.0</license><?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>service_demo</name>
  <version>0.3.4</version>
  <description>TODO</description>
  <maintainer email="demo@mail.com">Demo</maintainer>

  <license>Apache-2.0</license>
  <build_depend>rclcpp</build_depend><?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>service_demo</name>
  <version>0.3.4</version>
  <description>TODO</description>
  <maintainer email="demo@mail.com">Demo</maintainer>

  <license>Apache-2.0</license>
  <build_depend>rclcpp</build_depend>
  <build_depend>builtin_interfaces</build_depend>
  <buildtool_depend>rosidl_default_generators</buildtool_de<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>service_demo</name>
  <version>0.3.4</version>
  <description>TODO</description>
  <maintainer email="demo@mail.com">Demo</maintainer>

  <license>Apache-2.0</license>
  <build_depend>rclcpp</build_depend>
  <build_depend>builtin_interfaces</build_depend>
  <buildtool_depend>rosidl_default_generators</buildtool_depend>

  <exec_depend>rclcpp</exec_depend>
  <exec_depend>std_msgs</exec_depend>
  <exec_depend>rosidl_default_runtime</exec_depend>

  <member_of_group>rosidl_interface_packages</member_of_group>

</package>
pend>

  <exec_depend>rclcpp</exec_depend>
  <exec_depend>std_msgs</exec_depend>
  <exec_depend>rosidl_default_runtime</exec_depend>

  <member_of_group>rosidl_interface_packages</member_of_group>

</package>

  <build_depend>builtin_interfaces</build_depend>
  <buildtool_depend>rosidl_default_generators</buildtool_depend>

  <exec_depend>rclcpp</exec_depend>
  <exec_depend>std_msgs</exec_depend>
  <exec_depend>rosidl_default_runtime</exec_depend>

  <member_of_group>rosidl_interface_packages</member_of_group>

</package>

  <build_depend>rclcpp</build_depend>
  <build_depend>builtin_interfaces</build_depend>
  <buildtool_depend>rosidl_default_generators</buildtool_depend>

  <exec_depend>rclcpp</exec_depend>
  <exec_depend>std_msgs</exec_depend>
  <exec_depend>rosidl_default_runtime</exec_depend>

  <member_of_group>rosidl_interface_packages</member_of_group>

</package>


$ docker run -tid ubuntu:18.04
ba8e88b1d2e673d61be2716d2e2911d4e441f7bd62117cda1201904389e6f126

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
ba8e88b1d2e6        ubuntu:18.04        "/bin/bash"         3 seconds ago       Up 3 seconds                            awesome_diffie

$ docker exec -ti ba8e bash

容器中执行的操作:

  • 在容器中创建一个用户"admin",adduser admin
  • 在容器中安装openssh-server以便VSCode/CLion远程访问,
  • 测试openssh-server运行
root@ba8e88b1d2e6:/# adduser admin
Adding user `admin' ...
Adding new group `admin' (1000) ...
Adding new user `admin' (1000) with group `admin' ...
Creating home directory `/home/admin' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for admin
Enter the new value, or press ENTER for the default
        Full Name []: administrator
        Room Number []: 1
        Work Phone []: 1
        Home Phone []: 1
        Other []: 1
Is the information correct? [Y/n] Y

root@ba8e88b1d2e6:/# apt update && apt install openssh-server vim rsync build其中其中其中其中-essential -y
root@ba8e88b1d2e6:/# vim /etc/ssh/sshd_config 
root@ba8e88b1d2e6:/# mkdir /run/sshd
root@ba8e88b1d2e6:/# /usr/sbin/sshd
root@ba8e88b1d2e6:/# ssh admin@localhost
admin@ba8e88b1d2e6:~$

获取TX2根文件系统

在这里插入图片描述
由于之前给TX2刷机使用到Nvidia SDK manager, TX2的根文件系统会被缓存起来,缓存好的TX2根文件系统压缩文档是
~/Downloads/nvidia/sdkm_downloads/Tegra_Linux_Sample-Root-Filesystem_R32.1.0_aarch64.tbz2
host端执行如下操作

  • 将根文件系统压缩文档拷贝到容器中
  • 以admin用户登录到容器docker exec -ti ba8e login
$ docker cp Tegra_Linux_Sample-Root-Filesystem_R32.1.0_aarch64.tbz2 ba8e:/home/admin
$ winpty docker exec -ti ba login
ba8e88b1d2e6 login: admin
Password:
Last login: Mon Nov  9 02:45:16 UTC 2020 on pts/1
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.19.76-linuxkit x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.
admin@ba8e88b1d2e6:~$

容器中运行如下指令:

admin@ba8e88b1d2e6:~$ mkdir tx2-rootfs
admin@ba8e88b1d2e6:~$ tar xvf Tegra_Linux_Sample-Root-Filesystem_R32.1.0_aarch64.tbz2 -C tx2-rootfs
admin@ba8e88b1d2e6:~$ ls tx2-rootfs/
bin  boot  dev  etc  home  lib  media  mnt  opt  proc  root  run  sbin  snap  srv  sys  tmp  usr
admin@ba8e88b1d2e6:~$ rm Tegra_Linux_Sample-Root-Filesystem_R32.1.0_aarch64.tbz2

获取TX2的ROS及相关依赖库

容器中执行下面操作

  • 从TX2中拷贝ros2到tx2-rootfs根文件系统对应位置
admin@ba8e88b1d2e6:~$ rsync -av --progress nvidia@192.168.55.1:/opt/ros tx2-rootfs/opt
nvidia@192.168.55.1's password:
...........

admin@ba8e88b1d2e6:~$ ls tx2-rootfs/opt/ros/dashing/
_order_packages.py  bin  cmake  include  lib  local_setup.bash  local_setup.sh  local_setup.zsh  setup.bash  setup.sh  setup.zsh  share  src
admin@ba8e88b1d2e6:~$

构建依赖

下载新版本CMake

由于ubuntu18.04 apt install cmake所安装的版本是3.10.2,不支持add_link_options(),所以安装最新发布的cmake3.18.4。
从cmake官网下载最新的稳定发布版本3.18.4
如果官网下载速度过慢,可以从这里分流。

下载linaro交叉编译工具链

linaro gcc 最新官方下载渠道

拷贝构建工具到容器

host 执行下面指令:

  • 拷贝cmake linux安装包到容器中docker cp cmake-3.18.4-Linux-x86_64.sh ba:/usr/local/lib
$ docker cp cmake-3.18.4-Linux-x86_64.sh ba:/usr/local/lib
$ docker cp lia

容器中执行下面指令:

  • 安装交叉编译工具链gcc,g++
  • 安装cmake3.18.4(root用户)
  • 配置环境变量
  • 创建用于cmake交叉编译的通用文件cross.cmake
    host 通过root登录到容器中
$ docker exec -ti ba 

root@ba8e88b1d2e6:/usr/local/lib# ./cmake-3.18.4-Linux-x86_64.sh
root@ba8e88b1d2e6:/usr/local/lib# rm cmake-3.18.4-Linux-x86_64.sh
root@ba8e88b1d2e6:/usr/local/lib# tar xvf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-lin
ux-gnu.tar
root@ba8e88b1d2e6:/usr/local/lib# rm gcc-linaro-7.5.0-2019.12-x86_64_aarch64-lin
ux-gnu.tar
root@ba8e88b1d2e6:/usr/local/lib# mv gcc-linaro-7.5.0-2019.12-x86_64_aarch64-lin
ux-gnu/ gcc-linaro-7.5.0
root@ba8e88b1d2e6:/usr/local/lib# ls
cmake-3.18.4-Linux-x86_64  gcc-linaro-7.5.0  python3.6
root@ba8e88b1d2e6:/usr/local/lib#

配置用户环境变量

以普通用户登录容器后,修改用户环境变量文件vim ~/.bashrc
在~/.bashrc头部加上如下内容

CMAKE_HOME=/usr/local/lib/cmake-3.18.4-Linux-x86_64
export TX2_SYSROOT=/home/admin/tx2-rootfs
export ROS2_HOME=${TX2_SYSROOT}/opt/ros/dashing
export PYTHONPATH=${ROS2_HOME}/lib/python3.6/site-packages
export PATH=${PATH}:${CMAKE_HOME}/bin:${ROS2_HOME}/bin

创建cmake交叉编译文件

admin@ba8e88b1d2e6:~$ mkdir workspace && cd workspace && vim cross.cmake

cross.cmake内容如下

set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_PROCESSOR aarch64)

set(SYSROOT_PATH  /home/admin/tx2-rootfs)
set(CMAKE_SYSROOT "${SYSROOT_PATH}")
message(STATUS  "Using sysroot path as ${SYSROOT_PATH}")

set(TOOLCHAIN_PATH /usr/local/lib/linaro-7.3.1)
set(TOOLCHAIN_HOST ${TOOLCHAIN_PATH}/bin/aarch64-linux-gnu)

set(TOOLCHAIN_CC "${TOOLCHAIN_HOST}-gcc")
set(TOOLCHAIN_CXX "${TOOLCHAIN_HOST}-g++")
set(TOOLCHAIN_LD "${TOOLCHAIN_HOST}-ld")

set(CMAKE_CROSSCOMPILING TRUE)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_C_COMPILER ${TOOLCHAIN_CC})
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_CXX})
set(CMAKE_LINKER ${TOOLCHAIN_LD})

add_link_options("LINKER:-rpath-link,/home/admin/tx2-rootfs/lib/aarch64-linux-gnu:/home/admin/tx2-rootfs/usr/lib/aarch64-linux-gnu")

message(STATUS "cmake prefix: ${CMAKE_PREFIX_PATH}")

set(CMAKE_FIND_ROOT_PATH "${SYSROOT_PATH}" "${CMAKE_PREFIX_PATH}" "${TOOLCHAIN_PATH}/aarch64-linux-gnu/libc")
message(STATUS "cmake find root path is ${CMAKE_FIND_ROOT_PATH}")

# search for programs in the build host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

测试ROS2交叉编译

新创建一个包,命名为service_demo

  • package.xml的内容如下
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
  <name>service_demo</name>
  <version>0.3.4</version>
  <description>TODO</description>
  <maintainer email="demo@mail.com">Demo</maintainer>
  <license>Apache-2.0</license>
  <build_depend>rclcpp</build_depend>
  <build_depend>builtin_interfaces</build_depend>
  <buildtool_depend>rosidl_default_generators</buildtool_depend>
  <exec_depend>rclcpp</exec_depend>
  <exec_depend>std_msgs</exec_depend>
  <exec_depend>rosidl_default_runtime</exec_depend>
  <member_of_group>rosidl_interface_packages</member_of_group>
</package>
  • CMakeLists.txt内容如下:
cmake_minimum_required(VERSION 3.5)
project(service_demo)

set(CMAKE_CXX_STANDARD 14) 
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rosidl_default_generators REQUIRED)

rosidl_generate_interfaces(${PROJECT_NAME} "srv/ServiceDemo.srv")
ament_export_dependencies(rosidl_default_runtime)

add_executable(service_demo_server src/service_demo_server.cpp)
rosidl_target_interfaces(service_demo_server ${PROJECT_NAME} "rosidl_typesupport_cpp")
ament_target_dependencies(service_demo_server rclcpp) 

ament_package()
  • 自定义service文件srv/ServiceDemo.srv内容如下:
int64 a
int64 b
---
int64 sum
  • server源代码src/service_demo_server.cpp内容如下
#include "rclcpp/rclcpp.hpp"
#include "service_demo/srv/service_demo.hpp"

#include <memory>

void add(const std::shared_ptr<service_demo::srv::ServiceDemo::Request> request,
          std::shared_ptr<service_demo::srv::ServiceDemo::Response>      response)
{
  response->sum = request->a + request->b;
  RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Incoming request\na: %ld" " b: %ld",
                request->a, request->b);
  RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "sending back response: [%ld]", (long int)response->sum);
}

int main(int argc, char **argv)
{
  rclcpp::init(argc, argv);

  std::shared_ptr<rclcpp::Node> node = rclcpp::Node::make_shared("add_two_ints_server");

  rclcpp::Service<service_demo::srv::ServiceDemo>::SharedPtr service =
    node->create_service<service_demo::srv::ServiceDemo>("add_two_ints", &add);

  RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Ready to add two ints.");

  rclcpp::spin(node);
  rclcpp::shutdown();
}
  • client源代码src/service_demo_client.cpp内容如下
#include "rclcpp/rclcpp.hpp"
#include "service_demo/srv/service_demo.hpp"

#include <chrono>
#include <cstdlib>
#include <memory>

using namespace std::chrono_literals;

int main(int argc, char **argv)#include "rclcpp/rclcpp.hpp"
#include "service_demo/srv/service_demo.hpp"

#include <chrono>
#include <cstdlib>
#include <memory>

{
  rclcpp::init(argc, argv);

  if (argc != 3) {
      RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "usage: add_two_ints_client X Y");
      return 1;
  }

  std::shared_ptr<rclcpp::Node> node = rclcpp::Node::make_shared("add_two_ints_client");
  rclcpp::Client<service_demo::srv::ServiceDemo>::SharedPtr client =
    node->create_client<service_demo::srv::ServiceDemo>("add_two_ints");

  auto request = std::make_shared<service_demo::srv::ServiceDemo::Request>();
  request->a = atoll(argv[1]);
  request->b = atoll(argv[2]);

  while (!client->wait_for_service(1s)) {
    if (!rclcpp::ok()) {
      RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Interrupted while waiting for the service. Exiting.");
      return 0;
    }   
    RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "service not available, waiting again...");
  }
  
  auto result = client->async_send_request(request);
  // Wait for the result.
  if (rclcpp::spin_until_future_complete(node, result) ==
    rclcpp::executor::FutureReturnCode::SUCCESS)
  {
    RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Sum: %ld", result.get()->sum);
  } else {
    RCLCPP_ERROR(rclcpp::get_logger("rclcpp"), "Failed to call service add_two_ints");  
  }

  rclcpp::shutdown();
  return 0;
}

编译

$ mkdir build
$ cd build
$ cmake -DCMAKE_TOOLCHAIN_FILE=~/workspace/cross.cmake ..
$ make -j11

注意:自定义的msg、srv或action文件命名都必须是首字母大写,具体可以参考这里

谢谢关注,欢迎留言

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于docker搭建tx2的ROS2交叉编译环境 的相关文章

随机推荐

  • 学习总结:C++中STL的数据结构

    1 STL介绍 STL xff08 Standard Template Library xff09 xff0c 即标准模板库 xff0c 是一个具有工业强度的 xff0c 高效的C 43 43 程序库 它被容纳于C 43 43 标准程序库
  • 基于深度学习的移动网络异常检测

    1 文章信息 文章题为 Detection of mobile network abnormality using deep learning models on massive network measurement data xff0c
  • Multilinear Relationship Networks:多任务学习框架

    1 文章信息 文章题为 Learning Multiple Tasks with Multilinear Relationship Networks xff0c 该文章于2017年发表至Advances in neural informat
  • 学校人力资源管理系统——需求分析(一)

    需求分析 一 系统功能 1 通过表的创建过程进行数据的关联和约束 2 插入 修改 删除功能 3 查询功能 二 系统概要设计 本系统共有6个实体 xff0c 分别是教职工 xff0c 部门 xff0c 职称 xff0c 职务 xff0c 学籍
  • vsode 编译报错:main.c:4:10: fatal error: iostream: 没有那个文件或目录

    文档声明 xff1a 以下资料均属于本人在学习过程中产出的学习笔记 xff0c 如果错误或者遗漏之处 xff0c 请多多指正 并且该文档在后期会随着学习的深入不断补充完善 感谢各位的参考查看 笔记资料仅供学习交流使用 xff0c 转载请标明
  • JSON未定义解决办法

    https blog csdn net wanglei9876 article details 41752863 ie6 ie7下JSON parse JSON未定义的解决方法 解决方法一 xff1a var jsons 61 req re
  • datax抽取mongoDB只需要访问隐藏节点源码修改

    背景 由于在mongoDB的业务库数据量较大 且使用方比较多 搜索 业务方和数仓 使得主节点和其他从节点压力很大 为了不影响正常的业务 DBA新增了一台隐藏节点作为搜索和数仓抽取数据用 用datax抽取mongo的数据默认是主节点优先 所以
  • 禁忌搜索算法(Tabu Search)

    一 局部领域搜索 又称 爬山启发式算法 xff0c 从当前的节点开始 xff0c 和周围的邻居节点的值进行比较 如果当前节点是最大的 xff0c 那么返回当前节点 xff0c 作为最大值 即 山峰最高点 xff1b 反之就用最高的邻居节点替
  • Linux基础认识与简单命令的带图示范

    一 Linux的基础认识 Linux全称GUN Linux 是林纳斯 本纳第克特 托瓦兹于1991年10月5日首发 通常公司的服务器都用它是因为GUN是开源组织 xff0c 大家很多都一致Linux是操作系统 xff0c 其实Linux指的
  • MPU6050-扫盲

    文章部分内容转载于 https blog csdn net zmjames2000 article details 88379640 管脚名称说明VCC3 3 5V xff08 内部有稳压芯片 xff09 GND地线SCLMPU6050作为
  • OpenStack 虚拟机修改mac 地址

    查看虚拟机id root 64 controller01 source admin openrc 查看 ip 地址的port id root 64 controller01 neutron port list grep 190 b6c8eb
  • px4 makefile解析

    关于px4的编译的流程 xff0c 首先运行makefile xff0c 执行cmake xff0c 执行完之后再执行make命令 xff0c 完成整个编译流程 编译px4 v2的版本 xff0c 需要执行命令 xff1a make px4
  • px4 CMakeLists.txt解析

    上一篇中提到px4中的Makefile执行make时会调用cmake xff0c 下面对CMakeLists txt做出解析 整个文件分为两个部分 xff0c 前半部分实质是一些初始化工作 后半部分是涉及编译部分 第一部分 xff1a sp
  • px4 rcS脚本分析

    rcS是nuttx系统启动后 xff0c 执行的脚本 xff0c 主要实现对飞控外设以及核心算法模块的启动 先贴一张图 xff0c 这个图已经大致写出了rcS的流程 给出代码分析 有些地方没有分析到 xff0c 还望指正 1 rcS文件 s
  • FreeRTOS进不了任务 卡在SVC_Handler

    网上看的 xff1a 第一次移植FreeRTOS单步调试卡在SVC Handler 汇编上面看SVC Handler后面有个 WEAK xff0c 意思是如果该函数不存在也不报错 xff0c 这意思是SVC Handler不存在 xff0c
  • 学校人力资源管理系统——需求分析(二)

    四 数据字典 1 教 职工信息表 的数据字典如表所示 表1 教职工信息表的数据字典 列名 数据类型 长度 是否可空 说明 职工编号 定长字符串型 xff08 char xff09 6 主键 姓名 定长字符串型 xff08 char xff0
  • IIC通讯总结

    1 IIC简介 IIC全称Inter Integrated Circuit 是由PHILIPS公司在80年代开发的两线式串行总线 xff0c 用于连接微控制器及其外围设备 IIC属于半双工同步通信方式 2 IIC特点 xff08 1 xff
  • Opencv 创建图像时,CV_8UC1,CV_32FC3等参数的含义

    转载链接 xff1a http blog csdn net maweifei article details 51221259 CV lt bit depth gt S U F C lt number of channels gt 1 bi
  • 时间序列聚类方法的研究

    女主宣言 为了保证系统 服务的可靠性和稳定性 xff0c 监控系统日渐成为每个公司 企业的一个必不可少的系统 随着服务 机器等数量越来越多 xff0c 如何分析海量时间序列KPI成为我们在智能运维领域首先需要解决的问题 在众多的时间序列中
  • 基于docker搭建tx2的ROS2交叉编译环境

    基于docker搭建TX2的ROS2交叉编译环境 概述 ROS2官方文档有交叉编译相关说明 本文使用TX2最新官方镜像JetPack4 4版本 xff0c 自带ubuntu18 04 有现成的ubuntu18 04就可以使用apt get