深蓝学院-视觉SLAM十四讲-第一章作业

第1章作业

1. 熟悉Linux

  1. 请描述apt-get 安装软件的整体步骤,说明Ubuntu 是如何管理软件依赖关系和软件版本的。

注:阅读了鸟哥私房菜第23章的内容,该章主要讲述了RPM机制的软件安装方式。而ubuntu使用dpkg机制的软件安装方式,本人平时只是使用apt-get安装软件,并没有深入了解背后的安装原理,所以本题参考了ubuntu APT-GET工作原理 进行作答。

使用apt-get安装软件主要分为四步:

  • 扫描本地存放的软件包更新列表(由“apt-get update”命令刷新更新列表,也就是/var/lib/apt/lists/),找到最新版本的软件包;
  • 进行软件包依赖关系检查,找到支持该软件正常运行的所有软件包;
  • 从软件源所指 的镜像站点中,下载相关软件包;
  • 解压软件包,并自动完成应用程序的安装和配置。

Ubuntu 是如何管理软件依赖关系和软件版本:

​ 有时候在Ubuntu下安装软件包时会遇到提示说,下列软件包有未满足的依赖关系这样的问题。实际上linux的包是开源的,而这些包的编辑者大多数是一些大神为了方便使用某个功能编写的。恰好某个复杂功能里用到了这个小功能,那么作为程序员肯定是直接调用现成的。依赖的意思就是你用这个复杂功能之前需要使用某个包或者调用某个包。

​ 这里引入一个APT包管理工具的概念,Ubuntu上用与Debian一样的Deb软件管理工具,apt-get就是Ubuntu的Deb软件管理工具,即APT包管理工具。这个软件会从Ubuntu的软件源库里调用安装所需要安装的包,而且可以自动分析和解决依赖关系,并且将所依赖的软件都搞定。Ubuntu如果想安装指定版本的软件,可以在安装时在安装包名后边指定所要安装的版本即可。

  1. 什么是软件源?如何更换系统自带的软件源?如何安装来自第三方软件源中的软件?

软件源(软件仓库)一般指debian系操作系统的应用程序安装包仓库,其中存放大量的软件包,apt会从软件源中下载软件,在/ect/apt/soure.list中可以为apt配置软件源。

其实在Ubuntu中软件源还细分为两种:Ubuntu官方软件源和PPA软件源

​ Ubuntu 官方软件源中包含了 Ubuntu 系统中所用到的绝大部分的软件,它对应的源列表是 /ect/apt/soure.list。在这个文件中,记录了 Ubuntu 官方源的地址。像我们平时常用的清华源、阿里源等镜像地址,它其实和 Ubuntu 官方的镜像是相同的,我这里做了替换主要是为了加快 apt 安装和更新软件源的速度。

​ PPA 源出现的背景是因为系统自带的源是很有限的,我们肯定需要一些其他的软件包然而如果是直接下载deb格式的文件的话,又不能获取到更新和维护,所以这就用到了十分重要的 PPA 源了。

如何更新系统自带的软件源

#这里尽量添加新的软件源,而不要删除掉原来自带的ubuntu软件源
sudo gedit /etc/apt/sources.list
添加源  #国内开源镜像站点汇总   https://www.asfor.cn/server/mirror/index.html
sudo apt-get update

安装来自第三方软件源中的软件

我用的是Ubuntu18.04系统,安装搜狗拼音时直接下载deb安装包,用dpkg进行安装,使用 sudo apt install -f 进行修复,对于安装第三方软件没有什么特别的要求。但Ubuntu 16.04 自带的软件中心对第三方软件安装非常不友好,需要先安装gdebi工具,然后使用此工具进行第三方软件的安装。

  1. 除了apt-get 以外,还有什么方式在系统中安装所需软件?除了Ubuntu 以外,其他发行版使用什么软件管理工具?请至少各列举两种。

我知道的Ubuntu软件安装主要有以下几种方式:

  • 下载deb格式文件进行离线安装;使用dpkg命令进行安装和卸载deb安装包。

  • apt-get方式在线安装;主要用于在线从互联网的软件仓库中 搜索安装升级卸载 软件。

  • make方式安装;对于某些软件仓库没有的库或者安装包,或者下载过慢的这种情况,我们可以选择直接下载其源码,然后进行源码安装。通常分为四步:配置–>编译–>安装–>清除临时文件。

  • pip或者conda安装;这种方式并不是ubuntu自带的安装工具,但在特定的环境下需要使用这两种安装方式。

sudo dpkg -i 安装包 命令 
sudo apt-get install 安装包 命令卸载 

其它发行版本的软件管理工具:
在这里插入图片描述

​ Archlinux使用pacman进行软件包管理

  1. 环境变量PATH 是什么?有什么用途?LD_LIBRARY_PATH 是什么?指令ldconfig 有什么用途?

环境变量PATH:系统通过PATH这个环境变量来获得可执行文件所在的位置,然后运行一下对应的可执行文件。

LD_LIBRARY_PATH:程序已经成功编译并且链接成功后,使用LD_LIBRARY_PATH来搜索目录,该变量中只有动态库有意义。

Idconfig的作用:

ldconfig是一个动态链接库管理命令,为了让动态链接库为系统所共享,还需运行动态链接库的管理命令–ldconfig。Idconfig的用途,主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(lib.so),进而创建出动态装入程序(ld.so)所需的连接和缓存文件.缓存文件默认为 /etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表。

  1. Linux 文件权限有哪几种?如何修改一个文件的权限?

文件权限是指文件的访问控制,即那些用户和组群可以访问文件以及可以执行什么样的操作。默认情况下文件或目录的创建者即为该对象的属主。属主对文件或者目录有特别的操作权限。

访问权限规定三种不同类型的用户:

  • 文件属主(Owner): 文件的所有者,称为属主。
  • 同组用户(Group):文件属组的同组用户。
  • 其它用户(Others):可以访问文件的其他用户。

访问权限的表示方法有三种,即三组九位字母表示法、三组九位二进制表示法和三位八进制表示法。其中用r表示读,用w表示写,用x表示可执行可查找,用-表示无权限

文件权限的修改方法:

修改文件权限的命令是chmod,执行该命令要求必须为文件属主或者是root用户才能使用。有两种修改方法,字母形式修改权限;数字形式修改权限。

  • 字母形式修改权限;即“用户对象 操作符号 操作权限”
chmod [选项] 模式 [, 模式] 文件名
  • 数字形式修改权限
chmod 八进制模式 文件名
  1. Linux 用户和用户组是什么概念?用户组的权限是什么意思?有哪些常见的用户组?

Linux操作系统是多用户的分时操作系统,具有功能强大的用户管理机制,它将用户分为组,每个用户都属于某个组,每个用户都需要进行身份验证,同时用户只能在所属组所拥有的权限内工作,这样不仅方便管理,而且增加了系统的安全性。

**用户:**分为普通用户、管理员用户(root用户)和系统用户。普通用户在系统上的任务是进行普通的工作,root用户对系统具有绝对的控制权,但操作不当会对系统造成损毁。所以在进行简单任务是进行使用普通用户。

**用户组:**用户组是用户的容器,通过组,我们可以更加方便的归类、管理用户。用户能从用户组继承权限,一般分为普通用户组,系统用户组,私有用户组。当创建一个新用户时,若没有指定他所属于的组,系统就建立一个与该用户同名的私有组。当然此时该私有组中只包含这个用户自己。标准组可以容纳多个用户,若使用标准组,在创建一个新的用户时就应该指定他所属于的组。

  1. 常见的Linux 下C++ 编译器有哪几种?在你的机器上,默认用的是哪一种?它能够支持C++ 的哪个标准?

gcc和g++。我的电脑中默认用的是g++,它支持c++11标准。

2. SLAM综述文献阅读

  1. SLAM 会在哪些场合中用到?至少列举三个方向。

SLAM的应用场景主要有以下几个方向:

  • SLAM技术可用于增强现实(AR, Augmented reality),增强现实是一种在现实场景中无缝融入虚拟物体的一种技术,比如京东或者淘宝一些店铺提供的在线试鞋服务,抖音等提供的一些AR特效服务,利用平板可以观察选中的家具在自己房间摆放和搭配的效果。
  • SLAM在自动驾驶领域的应用,如无人驾驶利用激光雷达传感器来获取地图数据,构建地图,规避路程中遇到的障碍实现路径规划。
  • SLAM在机器人领域的应用,如扫地机器人等。
  • 无人机领域,无人机在飞行过程中需要知道哪里有障碍物,该怎么规避,怎么重新规划路线,显然需要用到slam技术。
  1. SLAM 中定位与建图是什么关系?为什么在定位的同时需要建图?

定位是为了精确地确定当前设备在某个环境中的姿态和位置;建图将周围环境的观测部分整合到一个单一的模型中。最初定位和建图是两个相互独立的关系,后来发现这两个步骤是相互依赖的。建图的准确性依赖于定位精度,而定位的实现又离不开精确的建图。

SLAM强调在未知环境下进行整个过程,如果在未知环境下进行定位,首先需要能够识别并理解周围的环境。再利用环境中的外部信息作为定位的基准,所以需要对所处的环境进行建图。

  1. SLAM 发展历史如何?我们可以将它划分成哪几个阶段?

概率SLAM问题最早起源于1986年在旧金山举办的IEEE机器人自动化会议中。经过几年的深耕,Smith等人发表了具有里程碑意义的论文。在最早提出SLAM的一系列论文中,当时的人们称它为“空间状态不确定性的估计”。而SLAM这一概念最早由Hugh Durrant-Whyte 和 John J.Leonard提出。SLAM主要用于解决移动机器人在未知环境中运行时定位导航与地图构建的问题。从SLAM的提出到现在已有三十多年,大致划分为以下几个阶段:

  1. 基于距离传感器的传统SLAM技术:SLAM技术最早是基于概率统计的扩展卡尔曼滤波的方法(EKF-SLAM),后来经过改进学者们提出了Fast SLAM方法,该方法大大减小计算量,提升运算速度。
  2. 基于视觉传感器的SLAM技术:2010年后,越来越多的SLAM系统采用视觉传感器作为主要的输入信号,提出了基于特征法的SALM基于直接法的SLAM
  3. SLAM技术未来研究热点将是多传感器融合SLAM语义SLAMSLAM于深度学习的结合

参考文献:

[1] H. Durrant-Whyte and T. Bailey, “Simultaneous localization and mapping: part I,” in IEEE Robotics & Automation Magazine, vol. 13, no. 2, pp. 99-110, June 2006, doi: 10.1109/MRA.2006.1638022.

[2] 刘明芹,张晓光,徐桂云,李宗周.单机器人SLAM技术的发展及相关主流技术综述[J].计算机工程与应用,2020,56(18):25-35.

  1. 从什么时候开始SLAM 区分为前端和后端?为什么我们要把SLAM 区分为前端和后端?

SLAM系统结构出现前后端应该是在出现基于视觉的SLAM方法之后,推测应该是在2010年之后,具体何时出现明确的前后端区别,我还不太清楚。

SLAM系统的体系结构包括两个主要部分:前端(或者叫视觉里程计)与后端。前端将传感器数据抽象成适用于估计的模型,估算相邻图像间相机的运动,以及局部地图的样子;而后端在这些经由前端处理的抽象数据上执行推理。后端接受不同时刻视觉里程计测量的相机位姿,以及回环检测的信息,对它们进行优化,得到全局一致的轨迹和地图。前后端所实现的功能不同,目的不同。

  1. 列举三篇在SLAM 领域的经典文献。

[1] Mur-Artal R, Montiel J M M, Tardos J D. ORB-SLAM: a versatile and accurate monocular SLAM system[J]. IEEE transactions on robotics, 2015, 31(5): 1147-1163.

[2] Davison A J, Reid I D, Molton N D, et al. MonoSLAM: Real-time single camera SLAM[J]. IEEE transactions on pattern analysis and machine intelligence, 2007, 29(6): 1052-1067.

[3] Durrant-Whyte H, Bailey T. Simultaneous localization and mapping: part I[J]. IEEE robotics & automation magazine, 2006, 13(2): 99-110.

3. CMake练习

参考资料:CMake Practice.pdf文档

1-4题

阅读CMake Practice.pdf后,开始组织代码文件和编写CMakeLists.txt。之前也并没有怎么接触过CMakeLists.txt编写,所以在初步编写是也出现了各种各样的问题。经过,出错->再看书->出错->网上搜->编写,最后终于可以运行1-4要求的格式。

代码的组织架构如下图所示:

在这里插入图片描述

cmd运行指令:

mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=/usr/local ..
make 
sudo make install
./sayHello

运行结果截图:

在这里插入图片描述

5.为我的库提供 FindHello.cmake 文件

遇到的问题1:cmake无法找到FindHELLO.cmake文件
在这里插入图片描述

网上查找资料,最后发现CMakeLists.txt文件中,下面的FIND_PACKAGE(Hello REQUIRED)这句代码中,Hello需要与FindHello.cmake的大小写匹配才可。修改后可正常运行,截图如下,最后运行./sayHello可正常运行。其中FindHello.cmake和CMakeLists.txt的编写代码文件可见。

在这里插入图片描述

4. gflags, glog, gtest的使用

参考资料:https://zhuanlan.zhihu.com/p/108477489

https://blog.csdn.net/alwaysrun/article/details/108418769

​ 1.gflags, glog, gtest的安装
使用命令行安装最简单,但是版本可能比较老。使用源码编译安装,安装步骤复杂,但可靠稳定。
使用命令行安装:

sudo apt-get install libgflags-dev
sudo apt-get install libgoogle-glog-dev
sudo apt-get install libgtest-dev

如果要删除的话,执行下边的命令

sudo apt-get remove libgflags-dev
sudo apt-get remove libgoogle-glog-dev
sudo apt-get remove libgtest-dev

使用源码编译安装:

gflags的安装

git clone https://ghproxy.com/https://github.com/gflags/gflags.git gflags_stable
cd gflags_stable
mkdir build
cd build
cmake .. -DGFLAGS_NAMESPACE=google -DCMAKE_CXX_FLAGS=-fPIC ..
make
sudo make install

glog的安装

git clone https://ghproxy.com/https://github.com/google/glog
sudo apt-get install autoconf automake libtool
cd glog
mkdir build
cd build
cmake ..
make
sudo make install

初次编译glog时如果出错,如下图所示,网上搜索解决方案,需要把glfag编译成动态库或者使用apt-get方法进行安装。

重新执行gflags的安装过程,将gflag编译成动态链接库
cmake -DGFLAGS_NAMESPACE=google -DCMAKE_CXX_FLAGS=-fPIC -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=ON -DINSTALL_HEADERS=ON -DINSTALL_SHARED_LIBS=ON -DINSTALL_STATIC_LIBS=ON -DCMAKE_INSTALL_PREFIX=/usr/ ..

在这里插入图片描述

gtest安装

git clone https://ghproxy.com/https://github.com/google/googletest.git
cd googletest
mkdir build
cd build
cmake ..
make
sudo make install

代码编写过程

2-3题:我直接将sayHello函数放入了useHello.cpp代码中,具体代码编写和CMakeLists.txt编写见代码文件。最后的日志文件如下图所示。

在这里插入图片描述

由于本人能力有限,gtest的编写过程理解不深,没能写出来。

5. 理解ORB-SLAM2框架

​ 1.ORB-SLAM2下载完成终端截图
在这里插入图片描述

  1. 阅读 ORB-SLAM2 代码目录下的 CMakeLists.txt,回答问题:
  • ORB-SLAM2将编译出什么结果?有几个库文件和可执行文件?

    CMakeLists.txt的51-71行:代码将由19个.cc文件生成一个动态链接库,在/lib文件夹下的libORB_SLAM2.so文件;

    85-86行:将会产生一个可执行文件 rgbd_tum;

    91-92行:将会产生一个可执行文件 stereo_kitti;

    95-96行:将会产生一个可执行文件 stereo_euroc;

    102-103行:将会产生一个可执行文件 mono_tum;

    106-107行:将会产生一个可执行文件 mono_kitti;

    110-111行:将会产生一个可执行文件 mono_euroc。

  • ORB-SLAM2 中的 include, src, Examples 三个文件夹中都含有什么内容?

    include和src文件夹下是一些需要编译成动态链接库文件的头文件和源代码。其中Tracking.cc主要是从图像中提取ORB特征;LocalMapping.cc这部分用来完成局部地图构建。LoopClosing.cc分为两个过程,分别是闭环探测和闭环校正。

    Examples:此目录下是Monocular(单目)、RGB-D、ROS和Stereo文件

  • ORB-SLAM2 中的可执行文件链接到了哪些库?它们的名字是什么?

    以stereo_kitti为例,可执行文件链接到了变量${PROJECT_NAME}$,而此变量是src文件夹下的代码文件构建的动态链接库 libORB_SLAM2.so。

在这里插入图片描述

另外还有OpenCV_LIBS、EIGEN3_LIBS、Pangolin_LIBRARIES、libDBoW2.so、libg2o.so库文件。

6. *使用摄像头或视频运行ORB-SLAM2

​ 1.编译 ORB-SLAM2截图,因为之前安装过pangolin、opencv和eigen3等库,所以在编译这一步没有出什么大的问题,且参照群里对于usleep的错误解决方案,解决了这个问题。

#执行编译的命令
cd ORB_SLAM2
chmod +x build.sh
./build.sh

在这里插入图片描述

​ 2. 如何将 myslam.cpp或 myvideo.cpp 加入到 ORB-SLAM2 工程中?请给出你的 CMakeLists.txt 修改方案。

如下图所示,在Examples文件夹中创建Task7文件夹,将提供的代码myvideo.cpp等放置到Task7文件夹下。
在这里插入图片描述

CMakeLists.txt文件编写:

在ORB-SLAM2原CMakeLists.txt文件基础上,添加如下命令

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/Task7)
add_executable(myvideo
        Examples/Task7/myvideo.cpp)
target_link_libraries(myvideo ${PROJECT_NAME})
  1. 运行 ORB-SLAM2

初次运行时报出如下错误,怀着忐忑的心情在群里@了助教韩爽,后来经过提示发现原来是myvideo.cpp中一些路径问题没有修改对。这里要特别感谢助教们的热心解答,即便是在中秋节也很热心的在群里帮助大家解决问题。感谢!!
在这里插入图片描述

成功运行orb-slam2的测试文件,如下图所示:

在这里插入图片描述

习题讲解补充内容

CMake练习

使用MESSAGE进行Debug

在这里插入图片描述

指定编译路径:

SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/output)

在这里插入图片描述

gflags, glog, gtest的使用

在这里插入图片描述
在这里插入图片描述

github地址: https://github.com/ximing1998/slam-learning.git
国内gitee地址:https://gitee.com/ximing689/slam-learning.git

  • 21
    点赞
  • 89
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 《视觉SLAM十四》第三章主要介绍了视觉SLAM中的关键技术——特征提取和描子。本章首先介绍了特征点的概念和特征点的选择原则。特征点即图像中具有鲁棒性和区分度的点,可以通过对其进行检测和描来进行特征匹配和跟踪。在进行特征提取时,作者介绍了常见的特征检测算法,如Harris角点检测、SIFT和SURF算法等,并对其进行了比较和分析。 接着,本章详细阐了特征描子的概念和作用。特征描子是对特征点周围区域的图像信息进行编码,以实现特征匹配和跟踪。常见的特征描子包括SIFT、SURF和ORB等。作者从描子的表示形式、计算方式和匹配方法等方面进行了介绍,并对它们进行了比较和评价。同时,还提到了基于二进制描子的方法,如BRIEF、BRISK和FREAK等。 在特征匹配方面,本章介绍了特征描子匹配的基本原理和流程。以基于特征点的视觉SLAM为例,作者详细解释了特征点的匹配过程,包括特征点的选择、特征点描子匹配和筛选等步骤。并介绍了如何通过验证特征点的三角化和PnP求解来估计相机的位姿。 此外,本章还介绍了一些特定场景下的特征点选择和提取策略,如动态环境下的特征点追踪和关键帧选择等。 综上所,《视觉SLAM十四》第三章主要介绍了特征提取和描子在视觉SLAM中的重要性和应用。通过对特征点的检测和描,可以实现特征匹配和跟踪,为后续的相机位姿估计和建图提供基础。该章内容详细且通俗易懂,对于学习和理解视觉SLAM有着重要的指导作用。 ### 回答2: 《视觉SLAM十四-Ch3》主要介绍了视觉SLAM(同时定位与建图)技术的基本原理和实现方法。本章主要涵盖了三维几何表示和变换、相机模型和相机姿态以及特征提取与匹配等内容。 首先,本章介绍了三维几何表示和变换的概念。通过介绍欧氏空间中的点、向量和坐标变换,深入解释了相机在三维空间中的位置和朝向的表示方式。同时,引入了齐次坐标和投影矩阵的概念,为后续的相机模型和姿态估计打下了基础。 其次,本章详细解了相机模型和相机姿态的原理与应用。其中,介绍了针孔相机模型,分析了图像坐标和相机坐标之间的映射关系。通过投影矩阵的推导,给出了透视投影和仿射投影的公式,并解释了相机焦距和主点的含义。此外,还介绍了如何通过计算相机的外参矩阵来估计相机的姿态,以及如何将图像坐标转换为相机坐标。 最后,本章介绍了特征提取与匹配的技术。首先,介绍了角点和边缘点的概念,以及如何利用差分和梯度计算来检测图像中的角点和边缘点。然后,介绍了如何通过特征描符来表示图像中的特征点,并通过特征匹配算法找到两幅图像之间的对应关系。特征提取与匹配是视觉SLAM中非常重要的步骤,对于后续的相机定位和建图至关重要。 综上所,《视觉SLAM十四-Ch3》通过系统地介绍了视觉SLAM技术的基本概念和实现方法,包括三维几何表示和变换、相机模型和相机姿态的原理与应用,以及特征提取与匹配的技术。这些内容为读者深入理解和掌握SLAM技术提供了很好的基础。 ### 回答3: 视觉SLAM(Simultaneous Localization and Mapping)是一种通过计算机视觉技术,实现机器智能的同时实时定位和地图构建的方法。在《视觉SLAM十四》第三中,主要介绍了视觉SLAM的基本概念和关键技术。 首先,解了视觉SLAM的理论基础,包括自我运动估计和地图构建两个部分。自我运动估计是通过相邻帧之间的视觉信息,计算相机在三维空间中的运动,从而实现机器的实时定位;地图构建是通过对场景中特征点的观测和跟踪,建立起一个三维空间中的地图。这两个过程相互影响,通过不断迭代优化,实现高精度的定位和地图构建。 接着,解了基于特征的视觉SLAM算法。特征提取与描是建立视觉SLAM系统的关键步骤,通过提取场景中的特征点,并为其生成描子,来实现特征点的匹配和跟踪。同时,还介绍了一些常用的特征点提取和匹配算法,如FAST、SIFT等。 在SLAM框架方面,本节还介绍了基于视觉的前端和后端优化。前端主要负责实时的特征跟踪和估计相机运动,后端则是通过优化技术,对前端输出的轨迹和地图进行优化求解,从而提高系统的精度和鲁棒性。 最后,本节提到了几个视觉SLAM的应用场景,如自主导航、增强现实等。这些应用对于实时高精度的定位和地图建立都有着很高的要求,因此,视觉SLAM的技术在这些领域有着广泛的应用前景。 总的来说,《视觉SLAM十四》第三视觉SLAM的基本概念和关键技术进行了系统的介绍。理论基础、特征提取与描SLAM框架和应用场景等方面的内容都给出了详细的解释和案例,有助于读者更好地理解和应用视觉SLAM技术。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hello689

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值