EVO进行轨迹评估

EVO进行轨迹评估

文章目录

  • EVO进行轨迹评估
  • 1 前言
    • 1.1 轨迹对齐
    • 1.2 尺度变换
    • 1.3 绝对轨迹误差ATE和相对轨迹误差RTE
    • 1.4 绝对姿态误差APE和相对姿态误差RPE
  • 2 安装evo
    • 2.1 evo安装
    • 2.2 相关报错
      • 2.2.1 版本不兼容问题
      • 2.2.2 解决PATH警告
    • 2.3 测试
  • 3 evo指令
    • 3.1 evo_traj
    • 3.2 evo_ape
    • 3.3 evo_rpe
    • 3.4 evo_res
    • 3.5 evo_config 命令详解
  • 4 evo支持数据格式
    • 4.1 KITTI
    • 4.2 TUM
    • 4.3 euroc
    • 4.4 将轨迹保存其它格式

1 前言

1.1 轨迹对齐

​ “对齐”(Alignment)通常指的是将两组数据(观测轨迹和真值)进行匹配的过程。这样做的目的是为了量化它们之间的差异,或者调整它们以使它们在空间或时间上更加一致。以下是几种常见的对齐方法和概念:

  1. 时间对齐
    • 如果轨迹数据在时间上不同步,时间对齐可能涉及重新采样或插值,以确保两个轨迹在相同的时间点上有对应的数据
  2. 空间对齐
    • **空间对齐可能涉及平移、旋转或缩放(尺度)**操作,以使两个轨迹在空间位置上更加吻合。
  3. 特征对齐
    • 在某些情况下,可能需要提取轨迹的关键特征(如拐点、速度峰值等),并对这些特征进行对齐,以便更容易地比较它们的动态特性。

evo中还提到了投影、下采样以及滤波

1.2 尺度变换

​ 实际上就是尺度的一个对齐,比如单目相机只有一个相对的尺度,而没有绝对尺度!

网上找一组图,表示对齐、尺度变换的作用!

在这里插入图片描述

1.3 绝对轨迹误差ATE和相对轨迹误差RTE

  • 绝对轨迹误差计算的每一个点对(待评估轨迹的点与真值轨迹的点)的绝对值误差。

A T E a l l = 1 N ∑ i = 1 N ∣ log ⁡ ( T g t , i − 1 T e s t i , i ) ∨ ∥ 2 2 , \mathrm{ATE}_{\mathrm{all}}=\sqrt{\frac{1}{N}\sum_{i=1}^{N}|\log(T_{\mathrm{gt},i}^{-1}T_{\mathrm{esti},i})^{\vee}\|_{2}^{2}}, ATEall=N1i=1Nlog(Tgt,i1Testi,i)22 ,

  • 相对轨迹误差计算的是,针对两条轨迹,分别计算第 k时刻和 k+Δ时刻的误差,然后这两个误差间再计算绝对值误差。

R P E a l l = 1 N − Δ t ∑ i = 1 N − Δ t ∥ log ⁡ ( ( T g t , i − 1 T g t , i + Δ t ) ) − 1 ( T e s t i , i − 1 T e s t i , i + Δ t ) ) ∨ ∥ 2 2 , \mathrm{RPE}_{\mathrm{all}}=\sqrt{\frac{1}{N-\Delta t}\sum_{i=1}^{N-\Delta t}\|\log\left(\left(T_{\mathrm{gt},i}^{-1}T_{\mathrm{gt},i+\Delta t})\right)^{-1}\left(T_{\mathrm{esti},i}^{-1}T_{\mathrm{esti},i+\Delta t}\right)\right)^{\vee}\|_{2}^{2}}, RPEall=NΔt1i=1NΔtlog((Tgt,i1Tgt,i+Δt))1(Testi,i1Testi,i+Δt))22 ,

在这里插入图片描述

描述上面两种误差ATE、RTE的结果,evo一般会给出下面几种不同的标准,以绝对姿态误差为例,计算了最大误差、最小误差等等

max:最大误差
mean:平均误差
median:误差中位数
rmse:均方根误差
sse:和方差、误差平方和
std:标准差

1.4 绝对姿态误差APE和相对姿态误差RPE

​ 这两个和上面两个的区别:计算ATE和RTE之前,需要进行轨迹对齐!如计算ATE需要对每一个姿态进行一个APE的计算。如果不对齐,那么误差就会很大!所以说,APE和RPE就像是ATE和RTE基础或原子操作!

2 安装evo

2.1 evo安装

  • 查看python版本,用于安装不同版本的evo
# ubuntu18自带的
python --vesion
>>Python 2.7.17		# 根据GitHub提示,支持Python 2.7 的最后一个evo 版本是1.12.0

# ubuntu20自带,python2、3检查命令不一样
python3 --version
>>Python 3.8.10
  • 源码编译(推荐)
git clone https://github.com/MichaelGrupp/evo.git  # 选择1.27那个版本
cd evo
pip install --editable . --upgrade --no-binary evo -i https://pypi.tuna.tsinghua.edu.cn/simple  # 源码编译的话,不需要自己安装依赖,依赖写在setup.py中,终端执行当前命令即可自动下载。
# 验证表明还是需要安装依赖,比如matplotlib

2.2 相关报错

  • 可能会出现的报错,比如matplotlib没有安装成功,脚本路径问题
ERROR: seaborn 0.13.2 has requirement matplotlib!=3.6.1,>=3.4, but you'll have matplotlib 3.1.2 which is incompatible.
Installing collected packages: argcomplete, natsort, numpy, numexpr, pytz, python-dateutil, tzdata, pandas, zstandard, ruamel.yaml.clib, ruamel.yaml, rosbags, seaborn, evo
  WARNING: The script natsort is installed in '/home/pj/.local/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
  WARNING: The scripts f2py, f2py3 and f2py3.8 are installed in '/home/pj/.local/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
  WARNING: The script rosbags-convert is installed in '/home/pj/.local/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.

2.2.1 版本不兼容问题

​ 需要 Matplotlib 的版本在 3.4 以上,且不能是 3.6.1。系统中安装的是 Matplotlib 3.1.2,所以需要升级 Matplotlib

你可以使用以下命令来升级 Matplotlib

pip install --upgrade matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple

如果你只想安装与 Seaborn 兼容的版本,可以这样做:

pip install "matplotlib!=3.6.1,>=3.4" -i https://pypi.tuna.tsinghua.edu.cn/simple

2.2.2 解决PATH警告

​ 当安装的脚本不在 PATH 中时,可以将 ~/.local/bin 添加到你的 PATH 环境变量中。这可以通过修改 shell 配置文件 .bashrc来实现 。

以下是步骤:

  1. 打开你的 shell 配置文件

    gedit ~/.bashrc
    
  2. 在文件末尾添加以下行:

    export PATH="$HOME/.local/bin:$PATH"
    
  3. 保存文件并关闭编辑器。

  4. 使修改生效:

    source ~/.bashrc
    

2.3 测试

命令行输入evo

ubuntu@ubuntu:~/evo/evo-1.12.0$ evo	
Initialized new /home/wheeltec-client/.evo/settings.json	# 初始化
usage: evo [-h] {pkg,cat_log} ...		# 使用方法

Python package for the evaluation of odometry and SLAM

Supported trajectory formats:	# 支持数据格式
* TUM trajectory files
* KITTI pose files
* ROS bagfile with geometry_msgs/PoseStamped, geometry_msgs/TransformStamped,
    geometry_msgs/PoseWithCovarianceStamped or nav_msgs/Odometry topics
* EuRoC MAV dataset groundtruth files

The following executables are available:

Metrics:
   evo_ape - absolute pose error	# 绝对姿态误差
   evo_rpe - relative pose error	# 相对姿态误差

Tools:		# 几种常用工具
   evo_traj - tool for analyzing, plotting or exporting multiple trajectories
   evo_res - tool for processing multiple result files from the metrics
   evo_ipython - IPython shell with pre-loaded evo modules
   evo_fig - (experimental) tool for re-opening serialized plots
   evo_config - tool for global settings and config file manipulation

3 evo指令

3.1 evo_traj

tum

evo_traj tum 0819_circle_01.txt 0819_circle_50.txt 0819_circle.txt --ref=0819_circle_enu_data.txt -p

-p后面默认是--plot_mode=xyz

kitti

evo_traj kitti

euroc

evo_traj euroc MH_data1.csv MH_data3.csv -v --full_check
  • -v : 以详细模式显示
  • --full_check : 对轨迹进行检查

3.2 evo_ape

  • 用途:计算绝对位姿误差

  • 绝对位姿误差常被用作比较估计轨迹和参考估计并计算整个轨迹误差的统计数据, 适用于测试轨迹的全局一致性。

  • 命令语法: evo_ape 数据格式 参考轨迹 估计轨迹 可选项

    • 数据格式: euroc, tum, kitti
  • 常用命令示例:

    evo_ape tum 0819_circle_enu_data.txt 0819_circle_01.txt -v -as --plot --plot_mode xyz --save_plot ./I_W --save_results ./1.zip 
    

    命令含义: 考虑平移和旋转部分误差的ape, 进行平移和旋转对齐,以详细模式显示,画图并保存计算结果。

  • 参数说明:

    • -r : 即 -pose_relation, 此参数可选, 若不添加此参数,则默认为 trans_part。 有如下可选项:
    可选项含义
    full表示同时考虑旋转和平移误差得到的ape,无单位(unit-less)
    trans_part考虑平移部分得到的ape,单位为m
    rot_part考虑旋转部分得到的ape,无单位(unit-less)
    angle_deg考虑旋转角得到的ape,单位°(deg)
    angle_rad考虑旋转角得到的ape,单位弧度(rad)
    • -v : 表示 verbose mode, 详细模式

    • -a :即 -align, 表示采用 SE(3) Umeyama 对齐。 除了 -a 外,其他可选项如下

    命令含义
    -a/–align采用SE(3) Umeyama对齐,只处理平移和旋转
    -as/–align --correct_scale采用Sim(3) Umeyama对齐,同时处理平移旋转和尺度
    -s/–correct_scale仅对齐尺度
    • -plot : 表示画图

      • --plot_mode : 选择画图模式, 二维图或三维图,默认为 xyz, 可选项有[xy, xz, yz, zx, zy, xyz].
      • --save_plot : 后跟保存图像的文件路径, 可以通过 evo_config 命令设置, 常见的可以保存为 png, pdf
    • -save_results : 后跟存储结果的压缩文件路径, 如 ./VINS.zip, 是一个压缩文件。

    • --help: 显示帮助信息, 格式为: evo_ape 格式 --help , 如 evo_ape euroc --help

3.3 evo_rpe

  • 用途:计算相对位子误差

  • 相对位姿误差不进行绝对位姿的比较,相对位姿误差比较运动(姿态增量)。相对位姿误差可以给出局部精度,例如slam系统每米的平移或者旋转漂移量。

  • 命令语法: evo_ape 数据格式 参考轨迹 估计轨迹 可选项

    • 数据格式: euroc, tum, kitti
  • 常用命令示例:

    evo_rpe euroc MH_data3.csv pose_graphloop.txt -r angle_deg \ 
      --delta 1 --delta_unit m -va --plot --plot_mode xyz \ 
      --save_plot ./VINSplot --save_results ./VINS.zip 
    

    命令含义: 求每米的旋转角的rpe,以详细模式显示,画图并保存计算结果。

  • 参数说明:

    • -r : 即 -pose_relation, 此参数可选, 若不添加此参数,则默认为 trans_part。具体参数选项内容 同 evo_ape,具体项可参见前一章节说明.
    • -d/--delta : 表示相对位姿之间的增量,后跟数值,默认为1, 然后通过 -u/–delta_unit 指定单位;
    • -u/--delta_unit : 表示增量的单位,可选参数为 f, d, r, m 分别表示 frames, deg, rad, meters 。默认为f。 当此参数为 f 时,则 -d/–delta必须为整型, 其余情况可谓浮点型;-d/–delta 和 -u/–delta_unit 联合起来表示衡量局部精度的单位,如 每米、每弧度、每百米等。
    • -v --plot --plot_mode xyz --save_results results/VINS.zip --save_plot : 这些参数同 evo_ape, 具体可参见前一章节说明。

3.4 evo_res

evo_res 1.zip 5.zip --save_table results_compare.csv

1.zip 5.zip 分别是两种不同算法的一个比较结果,通过上面算法的对比结果就可以得到其他的对比图!

处理多个轨迹

evo_res results/*.zip -p --save_table results/table.csv
evo_ape tum 0714_circle_enu_data.txt 0714_circle_01.txt -v -as --plot --plot_mode xyz --save_plot ./imu_wheel --save_results ./R1.zip

evo_ape tum 0714_circle_enu_data.txt 0714_circle_05.txt -v -as --plot --plot_mode xyz --save_plot ./imu_wheel_r5 --save_results ./R5.zip
evo_res *.zip -p --save_table 0714_circle.csv

3.5 evo_config 命令详解

  • 用途:全局设置和配置文件的操作
命令说明
evo_config show查看设计文件中的参数配置
evo_config set进行参数设置
evo_config generate导出配置到指定的json文件
evo_config reset将参数还原到默认值
evo_config show|set|generate|reset help将参数还原到默认值
  • evo_config set 命令最为常用,下面是几个常用的参数,其含义以及可选项
参数含义可选项
plot_export_format输出图像时图像存储格式常用png,pdf等
plot_linewidth作图时线的宽度matplotlib支持的宽度,默认1.5
plot_reference_color图像中参考轨迹的颜色black,red,green等
plot_reference_linestyle参考轨迹的线型matplotlib支持的线型,默认–
plot_seaborn_style图像背景和网格whitegrid,darkgrid,white,dark
plot_split是否分开显示/存储图像false/true
plot_figsize画图的图像大小默认宽高均为6,可使用其他值
table_export_format表格数据输出格式常用 csv,excel,latex,json
  • 命令示例

    # 将画图背景更改成白色网格 
    evo_config set plot_seaborn_style whitegrid  
     
    # 将字体改为衬线型并调为1.2倍大小 
    evo_config set plot_fontfamily serif plot_fontscale 1.2  
     
    # 将画图所使用的线型改为  
    evo_config set plot_reference_linestyle -  
     
    # 将所画图的图像大小调整为10 9(宽 高) 
    evo_config set plot_figsize 10 9  
     
    # 将参数还原到默认值 
    evo_config reset       
     
    # 导出配置 
    evo_config generate --pose_relation angle_deg --delta 1 --delta_unit m --verbose --plot --out rpe_config.json 
     
    # 导入配置 
    evo_rpe euroc MH_data3.csv pose_graphloop.txt -c rpe_config.json
    

4 evo支持数据格式

evo教程文档

​ 实际上对于原点来讲,画出它的轨迹,只需要知道平移即可。

4.1 KITTI

a b c d
e f g h
i j k l
0 0 0 1
# 保存轨迹的文件保留了变换矩阵T的前3行,即旋转和平移,每一个T在最终的轨迹文件中作为1行,如下顺序
a b c d e f g h i j k l

4.2 TUM

timestamp x y z q_x q_y q_z q_w # 每行都有 8 个数,其中包含时间戳(以秒为单位)、位置(平移)和方向(作为四元数),每个值之间用空格分隔:

4.3 euroc

# 有很多信息,只关注前面即可
timestamp x y z q_w q_x q_y q_z 

4.4 将轨迹保存其它格式

--save_as_bag--save_as_kitti--save_as_tum--save_as_bag2
bag
euroc
kitti否(无时间戳)否(无时间戳)*否(无时间戳)
tum
bag2

eg

# export a EuRoC groundtruth file to a TUM trajectory
evo_traj euroc data.csv --save_as_tum
# (will be saved as data.tum)

# export TUM trajectories to KITTI format
evo_traj tum traj_1.txt traj_2.txt traj_3.txt --save_as_kitti
# (will be saved as *.kitti)

# export TUM trajectories to ROS bagfile
evo_traj tum traj_1.txt traj_2.txt traj_3.txt --save_as_bag
# (will be saved as <timestamp>.bag with topics traj_1, traj_2 and traj_3)

# and so on...

本文参考如下链接:

github.com

SLAM轨迹精度评价工具evo简介与使用 (zhaoxuhui.top)

SLAM中的位姿与轨迹评价指标:APE、RPE、ATE、RTE (zhaoxuhui.top)

evo · PyPI

evo

evo/notebooks/metrics.py_API_Documentation.ipynb at master · MichaelGrupp/evo (github.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/873450.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot3.x 启动自动执行sql脚本

1 引言 某些项目在首次启动时&#xff0c;需要先手动创建数据库表&#xff0c;然后再手动写入初始数据才能正常使用。为了省去这个手动操作过程&#xff0c;我们可以使用Spring Boot启动时执行sql脚本的配置&#xff0c;全自动完成这个过程。 2 配置 具体配置如下&#xff1…

Python 调用手机摄像头

Python 调用手机摄像头 在手机上安装软件 这里以安卓手机作为演示&#xff0c;ISO也是差不多的 软件下载地址 注意&#xff1a;要想在电脑上查看手机摄像头拍摄的内容的在一个局域网里面(没有 WIFI 可以使用 热点 ) 安装完打开IP摄像头服务器 点击分享查看IP 查看局域网的I…

[Linux]:进程(下)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;Linux学习 贝蒂的主页&#xff1a;Betty’s blog 1. 进程终止 1.1 进程退出的场景 进程退出只有以下三种情况&#xff1a; 代…

flume 使用 exec 采集容器日志,转储磁盘

flume 使用 exec 采集容器日志&#xff0c;转储磁盘 在该场景下&#xff0c;docker 服务为superset&#xff0c;flume 的sources 选择 exec &#xff0c; sinks选择 file roll 。 任务配置 具体配置文件如下&#xff1a; #simple.conf: A single-node Flume configuration#…

Shader 渲染路径

实际的游戏开发中&#xff0c;场景中的光源肯定是更多、更复杂的&#xff0c;如果只有一个平行光的处理&#xff0c;完全不能满足需求。处理更多的光源&#xff0c;我们就需要了解Unity底层是如何处理这些光源的。 1、渲染路径是什么 渲染路径&#xff08;Rendering Path&…

Apache POl的使用(导出报表)

介绍 Apache POl是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是&#xff0c;我们可以使用 PO! 在 Java 程序中对Miscrosoft Office各种文件进行读写操作。一般情况下&#xff0c;POI都是用于操作 Excel 文件。 Apache POl的应用场景: 银行网银系统导出交…

中秋之美——html5+css+js制作中秋网页

中秋之美——html5cssjs制作中秋网页 一、前言二、功能展示三、系统实现四、其它五、源码下载 一、前言 八月十五&#xff0c;秋已过半&#xff0c;是为中秋。 “但愿人长久&#xff0c;千里共婵娟”&#xff0c;中秋时节&#xff0c;气温已凉未寒&#xff0c;天高气爽&#x…

助贷行业的三大严峻挑战:贷款中介公司转型债务重组业务

大家是否察觉到一种趋势&#xff1f;现如今&#xff0c;众多贷款辅助服务机构与专注于债务再构的公司之间形成了紧密的“联动”。有的选择将获取的贷款需求转介给债务重组方&#xff0c;有的则直接下场&#xff0c;动用自身资本参与债务重组业务。这一现象背后&#xff0c;究竟…

紫光展锐完成Android 15同步升级,驱动技术创新与生态共赢

近日&#xff0c;紫光展锐宣布&#xff0c;展锐5G移动平台T820、T770、T765、T760、T750以及4G平台T620、T619、T616、T615、T612、T606&#xff0c;完成Android 15同步升级。相较于过往Android发布&#xff0c;今年同步升级Android 15主要有三大提升&#xff1a; ■ 紫光展锐实…

Oracle版本简介手册

Oracle版本简介手册 图1—数据库发布路线图表 Oracle数据库的各个版本反映了其技术的发展历程和功能增强&#xff0c;从最早的Oracle 1&#xff08;1979年&#xff09;到最新的版本&#xff0c;每个版本都带来了新的特性和改进&#xff0c;以满足不断变化的企业需求。以下是Or…

2024 第七届“巅峰极客”网络安全技能挑战赛初赛 Web方向 题解WirteUp

EncirclingGame 题目描述&#xff1a;A simple game, enjoy it and get the flag when you complete it. 开题&#xff0c;前端小游戏&#xff0c;红点出不去就行 直接玩通关了 看看如何不玩也能拿到flag&#xff0c;flag存储在后端php文件内&#xff0c;前端找不到。 看一下…

uniapp使用uni-popup做底部弹出选项(vue3)

效果图 页面代码 <!-- 发票筛选弹出框 --><uni-popup ref"popupRef" type"bottom" border-radius"10px 10px 0 0" background-color"#fff"><h4 style"text-align: center;margin-bottom: 20px;">发票筛…

内推|京东|后端开发|运维|算法...|北京 更多岗位扫内推码了解,直接投递,跟踪进度

热招岗位 更多岗位欢迎扫描末尾二维码&#xff0c;小程序直接提交简历等面试。实时帮你查询面试进程。 安全运营中心研发工程师 岗位要求 1、本科及以上学历&#xff0c;3年以上的安全相关工作经验&#xff1b; 2、熟悉c/c、go编程语言之一、熟悉linux网络编程和系统编程 3、…

AMD Zen5芯片技术架构分析

AMD Zen 5架构深入研究 在Zen 5技术日上&#xff0c;AMD隆重推出了其最新锐龙9000系列—“Granite Ridge”以及Ryzen AI 300系列—“Strix Point”。此次展示深入剖析了公司下一代芯片的卓越性能与创新力。 AMD 一直在缓慢地公布 Zen 5 处理器的细节&#xff0c;但今天我们可以…

【QT】基础入门学习

文章目录 浅析Qt应用程序的主函数使用qDebug()函数常用快捷键Qt 编码风格信号槽连接模型实现方案 信号和槽的工作机制Qt对象树机制 浅析Qt应用程序的主函数 #include "mywindow.h"#include <QApplication>// 程序的入口 int main(int argc, char *argv[]) {//…

log4j靶场,反弹shell

1.用vulhub靶场搭建&#xff0c;首先进入目录CVE-2021-44228中&#xff0c;docker启动命令 2.发现端口是8983&#xff0c;浏览器访问http://172.16.1.18:8983/ 3.用dnslog平台检测dns回显&#xff0c;看看有没有漏洞存在 4.反弹shell到kali&#xff08;ip为172.16.1.18&#xf…

负载均衡--资源申请说明(三)

1.负载方式&#xff1a;分为四层负载和七层负载 2.负载协议&#xff1a;四层负载为TCP和UDP&#xff0c;七层负载为HTTP和HTTPS 4.负载端口&#xff1a;填写虚地址的端口&#xff08;一般与后端服务端口保持一致&#xff09; 5.真实服务IP&#xff1a;指被负载的后台真实服务…

抖音素材网站有哪些?这几个高质量的抖音无水印素材网站分享

在今天的互联网时代&#xff0c;独特而高质量的视频素材已成为抖音内容创作者的必备武器。如果你正在寻找能够让你的作品一鸣惊人的抖音素材&#xff0c;那么你来对地方了。接下来&#xff0c;我将为你详细介绍几个国内外优质的抖音无水印素材网站&#xff0c;帮助你的视频更加…

【数据分享】《中国城市统计年鉴》(1985-2023)全PDF版本 第一次补档

数据介绍 中国城市&#xff0c;如同一本生动的历史书&#xff0c;承载着经济、社会的快速变迁。《中国城市统计年鉴》记录了城市的发展轨迹&#xff0c;是我们理解城市化进程、洞察城市挑战的重要指南。 这份年鉴的数据庞大而详实&#xff0c;囊括了中国城市发展的多个方面。…

如何在极狐GitLab中添加 SSH Key?

本文分享如何生成 SSH Key 并添加到极狐GitLab 中&#xff0c;然后用 SSH Key 进行代码拉取。 极狐GitLab 是 GitLab 在中国的发行版&#xff0c;可以私有化部署&#xff0c;对中文的支持非常友好&#xff0c;是专为中国程序员和企业推出的企业级一体化 DevOps 平台&#xff0…