Hero Image
使用Cartographer进行建图

ubuntu22.04安装cartograph 源码安装 在我们的项目中,需要在ubuntu22.04下源码安装cartograph.可以按照以下步骤进行. git clone git@github.com:ros2/cartographer.git git clone git@github.com:ros2/cartographer_ros.git # 安装依赖项 absl c++扩展库,参考下install_abseil.sh里使用的absl版本 git clone git@github.com:abseil/abseil-cpp.git cd abseil-cpp git checkout 215105818dfde3174fe799600bb0f3cae233d0bf cd build cmake -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_POSITION_INDEPENDENT_CODE=ON \ -DCMAKE_INSTALL_PREFIX=/usr/local/stow/absl \ .. ninja sudo ninja install cd /usr/local/stow sudo stow absl # 安装 ceres 非线性优化库 sudo apt install libceres-dev # 安装lua 脚本语言库,提供配置文件解析 sudo apt install liblua5.3-dev # 安装protobuf 数据序列化开发库 sudo apt install protobuf-compiler libprotobuf-dev # 安装地图可视化库,支持轨迹绘制以及地图可视化 sudo apt install libcairo2-dev # 安装boost C++ 库集合 sudo apt install libboost-all-dev # 安装 Eigen3 线性代数库 sudo apt install libeigen3-dev # 编译cartographer_ros colcon build --packages-up-to cartographer_ros # rviz插件我们直接使用apt安装 sudo apt install ros-humble-nav2-rviz-plugins sudo apt install ros-humble-cartographer-rviz 保存地图 使用Cartographer进行建图时,可以将建图结果保存下来,我们这里可以采用ROS2自带的保存地图工具nav2_map_server.

Hero Image
Github错误处理

github 问题处理 分离指针 HEAD detached from ff8573b 分离头指针是说Git仓库的HEAD指针没有指向任何分支,而是直接指向一个特定的commit。正常情况下,HEAD应该指向一个确定的分支,但在分离头指针状态下,HEAD指向了某个commit。 以下指令会导致处于分离头指针状态: 直接检出了某个commit 检出远程指针时并没有在本地创建对应的本地分支 在主仓库中的submodule仓库(子模块)一般都处于分离头指针状态,这是因为主仓库对应的是子仓库的某一次提交,在检出时就会检出特定的commit提交,而不是某个分支。 HEAD detached from就是报告了github处于分离头指针状态,如果我们需要将当前的修改保存到main分支,则按照下述指令进行。 # 创建临时分支,保存修改 git branch temp # 切换到主分支 git checkout main # 合并temp 分支 git merge temp # 删除 temp 分支 git branch -d temp # 将修改推送到远程 git push origin main 拉取分支 将云端指定分支拉取到本地 # 获取远程分支信息 git fetch origin # 查看远程分支有哪些分支 git branch -r # 创建指定分支 git checkout -b dev origin/dev 丢弃提交 丢弃某一次commit 在项目开发中,如果进行了一次错误提交,需要删除这次提交所对应的修改,最安全的方式是创建一次新的commit来撤销之前的commit。 # 创建一个新的commit来撤销之前的commit git revert <commit-hash> 拉取仓库错误 拉取仓库错误 ssh: Could not resolve hostname github.com: Temporary failure in name resolution fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. 在wsl中拉取仓库中出现了这个错误,但是在宿主机是可以访问github的,这个问题是DNS原因导致的,可以按照如下步骤解决:

Hero Image
Docker的使用

Docker 使用 1. Docker基础概念 Image:Image是将运行的程序以及依赖等文件打包在一起。是程序的运行环境。 Container:Container是Image运行后形成的进程,一个Image可以创建1个或多个Container,每个Container之间是相互隔离的。 2. Docker image下载 下载指定平台的docker image sudo docker pull --platform linux/amd64 openjdk:21-jdk-slim` 当一个笔记本上的容器存在多个平台下的版本时,需要使用tag来进行区分 # 拉取 amd64 版本 docker pull --platform linux/amd64 mysql:latest docker tag mysql:latest mysql:amd64 # 拉取 arm 版本 docker pull --platform linux/arm64 mysql:latest docker tag mysql:latest mysql:arm 3. Docker 指令 启动 `sudo docker run -it --name myapp-container -p 8080:8080 myapp:latest /bin/bash` 开机自启动 打开开机自启动 sudo docker update --restart=always 容器名字或ID 关闭开机自启动 sudo docker update --restart=no 容器名字或ID 指定最大重启次数 sudo docker update --restart=on-failure:3 容器名或ID 查询容器自启动状态 sudo docker inspect -f "{{ .HostConfig.RestartPolicy.Name }}" 容器名或ID 4. Docker compose version: "3.8" services: db: image: mysql:latest restart: always environment: MYSQL_ROOT_PASSWORD: ****** # 设置root用户的密码 MYSQL_USER: userName # 创建一个新用户 MYSQL_PASSWORD: userName # 用户的密码 ports: - "3306:3306" # 映射MySQL端口到宿主机的3306端口 5. Docker 部署 本地保存Docker sudo docker save -o java21_x64.tar java21_x64:latest 上传文件到服务器 scp **** 服务器端加载docker `sudo docker load -i java21_x64.tar`

Hero Image
clangd的使用

clang clangd clangd 是一个语言服务器(Language Server),专门为 C/C++ 代码提供智能编辑功能。具有以下功能: 代码补全:智能提示函数、变量、类等 语法检查:实时检查语法错误 代码导航:跳转到定义、查找引用 重构支持:重命名、提取函数等 错误诊断:显示编译错误和警告 clang-format clang-format 是一个代码格式化工具,通过配置简单易懂的格式化选项,可以在保持代码功能不变的情况下,自动处理缩进、空格、括号、逗号等细节,提高代码的可读性和一致性,减轻代码审查和格式化的工作量,使代码维护更加高效。具有以下功能: 代码风格统一:自动调整缩进、空格、换行等 多种预设风格:Google、LLVM、Microsoft 等 自定义配置:支持 .clang-format 配置文件 批量格式化:可以格式化整个文件或代码块 clangd 与 clangd-format 特性 clangd clang-format 主要功能 语言服务器,智能编辑 代码格式化工具 运行方式 后台服务,持续运行 按需执行,一次性 输出结果 代码提示、错误诊断 格式化的代码 配置方式 编辑器集成配置 .clang-format 文件 使用场景 日常代码编辑 代码风格统一s 安装 ubuntu sudo apt-get install clangd sudo apt install clang-format windows LLVM-CLANG下载连接 安装vscode插件 在vscode中使用 在项目根目录或源代码所在目录下创建一个名为.clang-format的文件。 根据自己的编码风格偏好,在.clang-format文件中指定格式化选项,例如缩进、空格、括号风格等。 可以使用官方文档中提供的样式选项或自定义选项来配置文件。 保存.clang-format文件后,clang-format会在格式化代码时自动读取这些选项。 .clang-format文件详解 clang-format文件是用于配置clang-format的文件,采用基于YAML的格式。文件结构包括一系列的键值对,用于定义不同的格式化选项,其中格式化选项可以嵌套使用,形成层级结构。 .clang-format配置文件的常用格式化选项含义如下: --- # 语言: None, Cpp, Java, JavaScript, ObjC, Proto, TableGen, TextProto Language:Cpp # BasedOnStyle:LLVM # 访问说明符(public、private等)的偏移 AccessModifierOffset:-4 # 开括号(开圆括号、开尖括号、开方括号)后的对齐: Align, DontAlign, AlwaysBreak(总是在开括号后换行) AlignAfterOpenBracket:Align # 连续赋值时,对齐所有等号 AlignConsecutiveAssignments:true # 连续声明时,对齐所有声明的变量名 AlignConsecutiveDeclarations:true # 左对齐逃脱换行(使用反斜杠换行)的反斜杠 AlignEscapedNewlinesLeft:true # 水平对齐二元和三元表达式的操作数 AlignOperands:true # 对齐连续的尾随的注释 AlignTrailingComments:true # 允许函数声明的所有参数在放在下一行 AllowAllParametersOfDeclarationOnNextLine:true # 允许短的块放在同一行 AllowShortBlocksOnASingleLine:false # 允许短的case标签放在同一行 AllowShortCaseLabelsOnASingleLine:false # 允许短的函数放在同一行: None, InlineOnly(定义在类中), Empty(空函数), Inline(定义在类中,空函数), All AllowShortFunctionsOnASingleLine:Empty # 允许短的if语句保持在同一行 AllowShortIfStatementsOnASingleLine:false # 允许短的循环保持在同一行 AllowShortLoopsOnASingleLine:false # 总是在定义返回类型后换行(deprecated) AlwaysBreakAfterDefinitionReturnType:None # 总是在返回类型后换行: None, All, TopLevel(顶级函数,不包括在类中的函数), # AllDefinitions(所有的定义,不包括声明), TopLevelDefinitions(所有的顶级函数的定义) AlwaysBreakAfterReturnType:None # 总是在多行string字面量前换行 AlwaysBreakBeforeMultilineStrings:false # 总是在template声明后换行 AlwaysBreakTemplateDeclarations:false # false表示函数实参要么都在同一行,要么都各自一行 BinPackArguments:true # false表示所有形参要么都在同一行,要么都各自一行 BinPackParameters:true # 大括号换行,只有当BreakBeforeBraces设置为Custom时才有效 BraceWrapping: # class定义后面 AfterClass:false # 控制语句后面 AfterControlStatement:false # enum定义后面 AfterEnum:false # 函数定义后面 AfterFunction:false # 命名空间定义后面 AfterNamespace:false # ObjC定义后面 AfterObjCDeclaration:false # struct定义后面 AfterStruct:false # union定义后面 AfterUnion:false # catch之前 BeforeCatch:true # else之前 BeforeElse:true # 缩进大括号 IndentBraces:false # 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行) BreakBeforeBinaryOperators:NonAssignment # 在大括号前换行: Attach(始终将大括号附加到周围的上下文), Linux(除函数、命名空间和类定义,与Attach类似), # Mozilla(除枚举、函数、记录定义,与Attach类似), Stroustrup(除函数定义、catch、else,与Attach类似), # Allman(总是在大括号前换行), GNU(总是在大括号前换行,并对于控制语句的大括号增加额外的缩进), WebKit(在函数前换行), Custom # 注:这里认为语句块也属于函数 BreakBeforeBraces:Custom # 在三元运算符前换行 BreakBeforeTernaryOperators:true # 在构造函数的初始化列表的逗号前换行 BreakConstructorInitializersBeforeComma:false # 每行字符的限制,0表示没有限制 ColumnLimit:200 # 描述具有特殊意义的注释的正则表达式,它不应该被分割为多行或以其它方式改变 CommentPragmas:'^ IWYU pragma:' # 构造函数的初始化列表要么都在同一行,要么都各自一行 ConstructorInitializerAllOnOneLineOrOnePerLine:false # 构造函数的初始化列表的缩进宽度 ConstructorInitializerIndentWidth:4 # 延续的行的缩进宽度 ContinuationIndentWidth:4 # 去除C++11的列表初始化的大括号{后和}前的空格 Cpp11BracedListStyle:false # 继承最常用的指针和引用的对齐方式 DerivePointerAlignment:false # 关闭格式化 DisableFormat:false # 自动检测函数的调用和定义是否被格式为每行一个参数(Experimental) ExperimentalAutoDetectBinPacking:false # 需要被解读为foreach循环而不是函数调用的宏 ForEachMacros:[ foreach, Q_FOREACH, BOOST_FOREACH ] # 对#include进行排序,匹配了某正则表达式的#include拥有对应的优先级,匹配不到的则默认优先级为INT_MAX(优先级越小排序越靠前), # 可以定义负数优先级从而保证某些#include永远在最前面 IncludeCategories: - Regex:'^"(llvm|llvm-c|clang|clang-c)/' Priority:2 - Regex:'^(<|"(gtest|isl|json)/)' Priority:3 - Regex:'.*' Priority:1 # 缩进case标签 IndentCaseLabels:false # 缩进宽度 IndentWidth:4 # 函数返回类型换行时,缩进函数声明或函数定义的函数名 IndentWrappedFunctionNames:false # 保留在块开始处的空行 KeepEmptyLinesAtTheStartOfBlocks:true # 开始一个块的宏的正则表达式 MacroBlockBegin:'' # 结束一个块的宏的正则表达式 MacroBlockEnd:'' # 连续空行的最大数量 MaxEmptyLinesToKeep:1 # 命名空间的缩进: None, Inner(缩进嵌套的命名空间中的内容), All NamespaceIndentation:Inner # 使用ObjC块时缩进宽度 ObjCBlockIndentWidth:4 # 在ObjC的@property后添加一个空格 ObjCSpaceAfterProperty:false # 在ObjC的protocol列表前添加一个空格 ObjCSpaceBeforeProtocolList:true # 在call(后对函数调用换行的penalty PenaltyBreakBeforeFirstCallParameter:19 # 在一个注释中引入换行的penalty PenaltyBreakComment:300 # 第一次在<<前换行的penalty PenaltyBreakFirstLessLess:120 # 在一个字符串字面量中引入换行的penalty PenaltyBreakString:1000 # 对于每个在行字符数限制之外的字符的penalty PenaltyExcessCharacter:1000000 # 将函数的返回类型放到它自己的行的penalty PenaltyReturnTypeOnItsOwnLine:60 # 指针和引用的对齐: Left, Right, Middle PointerAlignment:Left # 允许重新排版注释 ReflowComments:true # 允许排序#include SortIncludes:true # 在C风格类型转换后添加空格 SpaceAfterCStyleCast:false # 在赋值运算符之前添加空格 SpaceBeforeAssignmentOperators:true # 开圆括号之前添加一个空格: Never, ControlStatements, Always SpaceBeforeParens:ControlStatements # 在空的圆括号中添加空格 SpaceInEmptyParentheses:false # 在尾随的评论前添加的空格数(只适用于//) SpacesBeforeTrailingComments:2 # 在尖括号的<后和>前添加空格 SpacesInAngles:true # 在容器(ObjC和JavaScript的数组和字典等)字面量中添加空格 SpacesInContainerLiterals:true # 在C风格类型转换的括号中添加空格 SpacesInCStyleCastParentheses:true # 在圆括号的(后和)前添加空格 SpacesInParentheses:true # 在方括号的[后和]前添加空格,lamda表达式和未指明大小的数组的声明不受影响 SpacesInSquareBrackets:true # 标准: Cpp03, Cpp11, Auto Standard:Cpp11 # tab宽度 TabWidth:4 # 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always UseTab:Never ... 如果不需要重新定义所有的规则,而是基于已有的代码风格模板进行修改,可以使用BasedOnStyle标识来进行部分格式规则的重定义: --- # We'll use defaults from the LLVM style, but with 4 columns indentation. BasedOnStyle: LLVM IndentWidth: 4 --- Language: Cpp # Force pointers to the type for C++. DerivePointerAlignment: false PointerAlignment: Left --- Language: JavaScript # Use 100 columns for JS. ColumnLimit: 100 --- Language: Proto # Don't format .proto files. DisableFormat: true --- Language: CSharp # Use 100 columns for C#. ColumnLimit: 100 ... 如果代码文件中有部分代码不希望采用.clang-format进行格式化,可以在这部分代码块的前后使用如下的注释进行标识: // clang-format off 这两个注释中间的代码不受clang-format的影响 // clang-format on 参考文章 ClangFormat

Hero Image
github 使用语法

github 语法流程图 本地初始化仓库 git init git add README.md git commit -m "first commit" git branch -M main git remote add origin git@github.com:user_name/test_init.git git push -u origin main 推送现有仓库到远程仓库 git remote add origin git@github.com:user_name/test_init.git git branch -M main git push -u origin main 克隆远程仓库到本地 git clone git@github.com:user_name/test_init.git 仓库管理 git init # 初始化新的Git仓库 git clone <url> # 克隆远程仓库 git remote add origin <url> # 添加远程仓库 git remote -v # 查看远程仓库 推送与拉取 git push origin <branch> # 推送到远程分支 git push -u origin <branch> # 设置上游分支并推送 git pull origin <branch> # 从远程拉取并合并 git fetch origin # 获取远程更新 git fetch --all # 获取所有远程更新 状态查看 git status # 查看工作区状态 git status -s # 简短格式显示状态 git log # 查看提交历史 git log --oneline -n # 单行显示最近n条提交历史 git log --graph # 图形化显示分支历史 git diff # 查看工作区与暂存区的差异 git diff --staged # 查看暂存区与HEAD的差异 文件操作 git add <file> # 添加文件到暂存区 git add . # 添加所有文件到暂存区 git add *.c # 添加所有.c文件 git rm <file> # 将文件从暂存区和工作区中删除 git rm --cashed <file> # 将文件从暂存区删除,工作区得以保留 git rm -f <file> # 将文件从暂存区和工作区中删除 git mv <old> <new> # 重命名文件 git checkout -- <file> # 从最近的一次提交中恢复文件,撤销工作区的修改,如果该文件曾经提交到 暂存区,则暂存区中的文件不受影响 git restore <file> # 恢复特定文件到暂存区状态 git restore . # 恢复所有文件到暂存区状态 提交管理 git commit -m "消息" # 提交更改 git commit -am "消息" # 添加并提交已跟踪的文件 git commit --amend # 打开编辑器,修改最后一次提交 git commit --amend -m "消息" # 直接修改最后一次提交 git reset HEAD <file> # 工作区不变,将本地仓库和暂存区修改到指定的<commit-hash> git reset --soft <commit-hash> # 暂存区,工作区不变,将本地仓库修改到指定的<commit-hash> git reset --hard HEAD # 完全重置到最后一次提交,暂存区,工作区,本地仓库均变化 分支管理 git branch # 查看本地分支 git branch -a # 查看所有分支,本地和远程 git branch <name> # 创建新分支 git checkout <branch> # 切换到指定分支 git checkout -b <name> # 创建并切换到新分支 git branch -d <name> # 删除分支 git branch -m <old> <new> # 重命名分支 合并与变基 git merge <branch> # 合并当前分支到<branch>分支,在流程图中有交叉 git rebase <branch> # 变基操作,将当前分支合并到<branch>分支,在流程图中没有交叉 git cherry-pick <commit-hash> # 将特定的<commit-hash>提交从一个分支引入到当前分支 标签管理 git tag # 查看所有标签 git tag <name> # 创建标签 git tag -a <name> -m "消息" # 创建带注释的标签 git push origin --tags # 推送所有标签 搜索查看 git show <commit> # 显示指定提交的详细信息 git blame <file> # 查看文件的每一行是谁修改的 git grep "关键词" # 在仓库中搜索关键词 git log -S "关键词" # 搜索包含关键词的提交 清理维护 git clean -n # 预览要清理的文件 git clean -f # 强制清理未跟踪的文件 git gc # 垃圾回收 git prune # 清理孤立的提交 stash操作 git stash # 将工作区,暂存区放置到 stash 区域,会删除工作区,暂存区的修改 git stash list # 查看 stash 列表 git stash pop <commit-hash> # 将stash区域保存的<commit-hash>状态恢复到工作区,暂存区,并删除该stash状态 git stash apply <commit-hash> # 将stash区域保存的<commit-hash>状态恢复到工作区,暂存区,不删除该stash状态

Hero Image
rviz可视化Marker

ROS2 visualization_msgs::msg::Marker 使用指南 1. Marker 简介 visualization_msgs::msg::Marker 是 ROS2 中用于在 RViz 可视化各种图形(如点、线、面、模型等)的消息类型,用来表示一个单独的可视化对象(比如一个点、一条线、一个球体等)。通过发布 Marker 消息,可以在 RViz 中动态显示调试信息、地图、轨迹等。 2. 常用 Marker 类型 POINTS:显示一组点 LINE_STRIP:显示一条折线 LINE_LIST:显示多条线段 SPHERE、CUBE、CYLINDER:显示几何体,分别为3D球体,立方体和圆柱体 TRIANGLE_LIST:显示三角面片 SPHERE_LIST:显示一组球体 CUBE_LIST:显示一组立方体 CYLINDER_LIST:显示一组圆柱体 3. 代码示例 以下代码展示了如何在 ROS2 中发布点云(POINTS 类型)的 Marker: // 1. 包含必要的头文件 #include <rclcpp/rclcpp.hpp> #include <visualization_msgs/msg/marker.hpp> #include <visualization_msgs/msg/marker_array.hpp> #include <geometry_msgs/msg/point.hpp> // 2. 创建 Marker 消息 visualization_msgs::msg::Marker marker; marker.header.frame_id = "map"; // 坐标系名称,需与 RViz 保持一致 marker.header.stamp = node->now(); // 时间戳 marker.ns = "example_points"; // 命名空间,可用于分组 marker.id = 0; // Marker 的唯一ID,同一ns下不能重复 marker.type = visualization_msgs::msg::Marker::POINTS; // Marker 类型:点云 marker.action = visualization_msgs::msg::Marker::ADD; // 动作:添加 // 3. 设置点的大小(宽和高,单位:米) marker.scale.x = 0.2; // 点的宽度 marker.scale.y = 0.2; // 点的高度 marker.scale.z = 0.2; // 点的深度 // 对 POINTS 类型,marker.scale.z 无效 // 4. 设置点的颜色(RGBA,范围0~1) marker.color.r = 1.0f; // 红色分量 marker.color.g = 0.0f; // 绿色分量 marker.color.b = 0.0f; // 蓝色分量 marker.color.a = 1.0f; // 透明度(1为不透明) // 5. 添加点数据 geometry_msgs::msg::Point p1, p2; p1.x = 1.0; p1.y = 2.0; p1.z = 0.0; p2.x = 2.0; p2.y = 3.0; p2.z = 0.0; marker.points.push_back(p1); marker.points.push_back(p2); // 6. 发布 Marker visualization_msgs::msg::MarkerArray marker_array; marker_array.markers.push_back(marker); marker_pub->publish(marker_array); 详细注释说明 header.frame_id:指定 Marker 所在的坐标系,RViz 必须有该坐标系。 header.stamp:时间戳,建议用 node->now()。 ns 和 id:用于唯一标识一个 Marker,更新/删除时需一致。 type:Marker 的类型,决定显示方式。 scale.x/y:点的宽高,必须都大于 0。 color:点的颜色和透明度。 points:点的坐标列表。 action:常用为 ADD,也可用 DELETE 删除。 4. 面色 有时需要将地图某一部分区域绘制出来,此时可以采用三角形“扇形剖分”的方式填充出来,将Marker类型设置为TRIANGLE_LIST,然后设置颜色进行显示。