SLAM论文详解(5) — Bundle_Adjustment_LM(BALM)论文详解
目录
1 摘要
2 相关工作
3 BA公式和导数
A. 直接BA公式
B. 导数
C. 二阶近似
4 自适应体素化
5. 将BALM结合进LOAM
6. 实验
7. 算法应用场景解析
1 摘要
Bundle Adjustment是一种用于同时估计三维结构和传感器运动运动的优化算法。在视觉SLAM,三维重建等应用中,它被广泛用于优化相机位姿和地图的精度。在视觉slam中,BA通过最小化特征之间的重投影误差,有效得优化相机位姿和地图的一致性,从而提高SLAM系统的精度和鲁棒性。
然而来到激光雷达这边情况就很不一样:激光雷达点云虽然拥有深度信息,但是比起图像比较稀疏,单帧的出点量和图像中的像素数量根本不在一个量级,导致特征点稀疏,特征匹配对应难做。那么有没有办法解决激光SLAM中的BA优化问题,让它可以在后端优化、雷达外参优化等应用上发挥作用呢?MARS实验室2021年6月发表在RAL的论文《Bundle Adjustment for LiDAR Mapping》给出了一个切实可行的方案。
在本文中,我们将激光BA建模为将特征点与其匹配的边缘或平面之间的距离最小化。与视觉SLAM(以及激光SLAM中先前的平面调整方法)不同的是,特征点可以通过解析方法求解并从BA中移除,得到的BA只依赖于扫描位姿。这大大减少了优化的规模,并允许使用大规模稠密的平面和边缘特征。为了加速优化过程,我们以闭合形式导出了代价函数的解析导数,包括二阶导数。此外,我们提出了一种新颖的自适应体素化方法,以高效地搜索特征对应关系。所提出的建模方法已应用于LOAM后端进行地图优化。结果表明,尽管作为后端,局部BA可以非常高效地求解,甚至在实时优化20个点云扫描时也能达到10Hz的速度。局部BA还显著降低了LOAM的漂移。
2 相关工作
3 BA公式和导数
A. 直接BA公式
为了高效解决激光点云的特征稀疏以及难以匹配的问题,BALM中借助八叉树的数据结构实现了自适应体素化的特征提取操作:首先对这个局部地图进行体素化操作:将构建的地图分割成一个个预设体积的体素,其中记录了这个点云来自第几帧,也就能找到它对应的雷达位姿,然后对每个体素分别计算这个体素内所有点的协方差矩阵。其中代表一个体素内的点数量。记为协方差矩阵中第大的特征值,那么就可以提取线面特征:
- 面特征:如果与的比值超越某一阈值,那么就标记为一个面特征体素。面特征的法向量为对应的特征向量
- 线特征:如果与的比值小于某一阈值,那么就标记为一个线特征体素。线特征的方向向量为对应的特征向量
如果满足上述任一条件,那么这个体素就会被标记为一个线或者面特征体素。如果不满足平面体素的条件,那么就将这个体素分成八个小体素,然后对这八个小体素分别判断是不是满足上述条件,不断递归直到八叉树的层数达到预先设定的最大值。这样就可以实现对局部地图快速且通用的特征提取,不需要使用检测、分割的方法,也不关心雷达型号(机械式还是固态),具有非常强的通用性。在开源代码中,堆叠了局部地图之后,使用cut_voxel()的函数对局部地图进行体素化并建八叉树,然后通过OCTO_TREE::recut()实现对局部地图的自适应体素化特征提取,然后对不同体素中的点云给不同的着色进行相应的可视化操作。
在对地图进行了自适应体素分割之后,特征的对应关系就很好做了:对于任一被标记为平面特征的体素,可以认为同一个体素内的所有点构成对应关系。从而可以构建点面误差或者点线误差:
- 点面:对于每一个平面体素,点面误差计算表达式如下:其中是平面体素中的任意一个点。理论上随便选特征体素中的某个点作为参照不影响损失函数的计算的结果,毕竟它们都应该在同一个面上。
- 点线:对于每一个线特体素,点线误差计算表达式如下:同理是线特征体素中的任意一个点。理论上随便选特征体素中的某个点作为参照不影响损失函数的计算的结果,毕竟它们都应该在同一个面上。
给定一组稀疏特征点,这些特征点来自于个扫描,但都对应于同一个特征(平面或边缘)(见图3)。假设第 i 个特征点来自于第个扫描,其中,将个扫描的姿态表示为,其中。然后,全局坐标系中的特征点为:
如前所述,激光雷达BA问题是指联合确定个扫描的姿态和全局三维点云地图。现在,三维地图是一个单一的特征(边缘或平面),那么BA问题就简化为联合确定单一特征的姿态和位置,该特征由特征上的点和单位向量(是平面的法向量或边缘的方向)表示。对于平面特征,直接BA公式是最小化每个平面特征点到平面上的距离的平方和:
其中表示矩阵的第k个最大特征值,是对应的特征向量,和分别表示:
与平面特征类似,边缘特征的直接BA公式是最小化每个边缘特征点到边缘的平方距离的总和:
其中 表示的迹。
注意,在公式(2)和(4)中,最优点 并不唯一,因为该点可以在平面内(或沿边缘)自由移动。然而,这对最终的优化代价函数没有影响。此外,公式(2)和(4)暗示了在BA之前可以解析地获得最优的特征(平面或边缘)参数,而最终的BA问题只依赖于姿态T。这与我们的直觉相符,即一旦扫描姿态确定,3D点云地图(因此平面或边缘特征)也就确定了。此外,对姿态T的优化转化为最小化公式(3)中矩阵A的特征值。即,BA导致最小化
在T上,其中 是与相同特征对应的所有特征点的向量。 为了使成本函数(5)的优化更加高效,我们对位姿T进行了解析地计算了一阶和二阶的闭合导数。由于链式法则,我们首先对点向量p进行了导数的计算。
对于上述的线面特征,取整个体素内点云的质心和方差,那么点面误差和点线误差就可以有如下的简化:
- 点面误差:将特征平面上的参考点取成质心,法向量取成最大的特征值对应的特征向量时,最优化的位姿对应于最小化方差矩阵的最大特征值的问题
- 点线误差:将线特征上的参考点取成质心,法向量取成最小的特征值对应的特征向量时,最优化的位姿对应于最小化方差矩阵的特征值的问题
也就是因为这个特性,无论是线特征还是面特征,我们可以将优化问题简化为一个关于雷达位姿的“最小化体素中方差矩阵的特征值”问题
其中是同一个体素中来自不同帧的点云坐标。区别于视觉SLAM中BA优化问题中每一轮的特征会随着位姿的变化而变化,在激光SLAM的一轮BA优化中,一旦位姿被确定,地图被构建,线面特征提取的结果也都是一样的,损失函数的只和待优化的位姿有关,特征点都已经被解析得计算出来,不再显式得参与计算。
B. 导数
定理1:对于一组点和在(3)中定义的协方差矩阵。假设 具有对应于特征向量的特征值,则
其中是N个点的平均值,如(3)中所示。
定理2:对于一组点 和在(3)中定义的协方差矩阵。假设具有对应于特征向量的特征值。此外,当时,则
C. 二阶近似
利用前面章节中的一阶和二阶导数,我们可以通过其二阶近似来近似成本函数(5),如下所示:
其中J(p)是Jacobian矩阵,其i元素在(6)中,H(p)是Hessian矩阵,其i行,j列元素在(7)中。
请注意,点向量p还依赖于扫描姿势T,如(1)所示。使用在[38]中定义的操作将姿势扰动到其切平面,我们有:
和
将(12)代入(8)得到
最后,我们使用Levenberg-Marquardt(LM)[39]方法通过反复将其近似为二阶近似(13)来最小化成本。在每次迭代中,解决方案从中解决
其中 是根据LM方法确定的步长。
4 自适应体素化
在第三节中,BA公式需要找到所有与同一特征(边缘或平面)对应的特征点。为此,我们提出了一种新颖的自适应体素化方法:假设存在不同扫描的粗略初始姿态(例如来自LOAM里程计),我们重复从默认尺寸(例如1米)开始对3D空间进行体素化:如果当前体素中的所有特征点(来自所有扫描)都位于平面或边缘上(例如通过检查点协方差矩阵的特征值(3)),则将当前体素与其中的特征点保存在内存中;否则,当前体素分解为八个八分体,并继续检查每个八分体,直到达到最小尺寸(例如0.125米)。所提出的自适应体素化生成一个体素地图,其中不同的体素可以根据环境进行不同的尺寸调整。对于每个体素,它对应于一个特征,因此对应于(13)中的一个成本项。图4(a)展示了一个示例体素地图。
自适应体素化具有许多优点:1)它与现有的数据结构(如八叉树)自然兼容,因此可以大大简化其实现和效率;2)与构建特征点的完整Kd树[10]相比,它通常更高效,因为当包含的特征点位于同一平面或边缘上时,可以提前终止。当环境具有大型平面或长边缘时,这种优势将更加明显;3)具有自适应体素的地图将减少在激光雷达里程计中搜索特征对应关系的时间。只需要搜索特征点所在或附近的体素,而不是需要更详尽搜索的最近点[10]。
在我们的实现中,我们构建了两个体素地图,一个用于边缘特征,一个用于平面特征。由于其构造方式,体素地图自然适合八叉树结构。为了减少八叉树的深度,我们使用一组由哈希表索引的八叉树(见图4(c))。每个八叉树对应空间中默认体素尺寸(例如1米)的一个非空立方体。不同的八叉树可能具有不同的深度,取决于空间中该立方体的几何形状。每个叶节点(即体素)保存与同一特征(例如平面或边缘)对应的所有特征点。
备注1:如果一个体素包含太多的点,(8)中的Hessian矩阵将具有非常高的维度,在这种情况下,我们可以对同一扫描的点进行平均。平均后的点数量较少,并且位于由原始特征点确定的同一平面上。这样可以节省大量计算而不会降低地图的一致性。
备注2:定理2中计算的Hessian矩阵要求当i≠k时,λi≠λk。对于具有超过一个代数重数的λk的体素,我们简单地跳过它。
备注3:尽管我们一直在提到边缘特征和平面特征,但该方法自然地可以扩展到非平面特征(例如曲面),方法是在更细的层次上构建体素地图,并允许在检查包含点是否位
自适应体素化具有许多优点:
- 它与现有的数据结构(如八叉树)自然兼容,因此可以极大地简化其实现和效率;
- 与构建完整的特征点Kd树相比,它通常更高效,因为当包含的特征点位于同一平面或边缘上时,可以提前终止。当环境具有大平面或长边缘时,这种优势将更加明显;
- 具有自适应体素的地图将减少在激光雷达里程计中搜索特征对应关系所需的时间。只需要搜索特征点所在或附近的体素,而不是需要更多穷举搜索的最近点。
5 将BALM结合进LOAM
由于激光SLAM中的运动估计通常是基于IMU和里程计,因此会存在累计误差。因此,应用BA优化可以有效地纠正这些累计误差,提高SLAM系统的精度和鲁棒性。原文中把LOAM的后端换成了BALM,对odometry进行后端优化。同时通过共享内存的方式将自适应体素化特征提取的结果用于前端的registration来进行加速。
我们将提出的BA公式和其优化方法纳入到LOAM框架中。系统概述如图5所示。它由三个并行线程组成:特征提取、里程计和地图优化。
一旦接收到新扫描的特征点,里程计通过将新的特征点与现有地图进行配准来估计激光雷达的姿态。与现有方法不同的是,我们利用自适应体素地图来加速匹配过程。具体而言,在构建体素地图时,我们计算体素中平面(或边缘)的中心点和法向量(或方向向量)。然后对于新扫描的特征点,我们通过计算该点与体素中的平面或边缘特征之间的距离来搜索最近的体素(由其中心点表示)。
使用里程计,可以将新的扫描点大致注册到全局坐标系,并将其推送到体素地图中:对于新扫描中的每个点,搜索其所在的体素,并将该点添加到相应八叉树的叶节点中。如果在现有地图中找不到与新扫描中的点对应的体素,则创建一个新的八叉树,将其根索引到哈希表中,并将该点添加到根节点中。在将新扫描的所有特征点分布到现有八叉树的叶节点或新创建八叉树的根节点后,我们按照构造方式更新体素地图:如果节点(叶节点或节点)中的点不能构成一个单一的特征(平面或边缘),则将该节点分割为八个并检查每个节点。
在将一定数量的新扫描推送到体素地图后,会触发地图优化。地图优化在激光雷达姿态的滑动窗口上执行局部BA。滑动窗口内包含的任何包含点的体素(即Psw)将用于构建成本项,如(2)或(4)。然后,地图优化反复最小化由所有相关体素组成的总成本的二阶近似(13)。这将优化滑动窗口内的所有激光雷达姿态。更新后的姿态然后用于更新所有相关体素的中心点和法向量。
一旦滑动窗口装满,来自较早扫描的点将合并到地图点中。点协方差矩阵(3)的一个良好特性是存在递归形式[40],允许将滑动窗口外的所有点汇总为几个紧凑的矩阵和向量,而无需保存原始点(参见图5的下部)。合并后的点将保留在体素地图中,用于里程计和地图优化。
6 实验
在整个论文的Experiment中体现出了这个算法如下几个特性:
- 精度高:手持场景下使用Livox Horizon绕HKU校园一圈回到终点,发现用BA作为后端的LOAM平移量飘了31cm,而纯LOAM平移量飘了6.23m。同时跑了一组室内数据,可以发现偏移量非常小,可见用它来做后端优化还是有比较高的精度的。
- 不挑lidar:原论文在Livox Horizon, Livox Mid40和VLP-16上都跑了实验,无论雷达多少FOV,扫出来点云什么样,都可以跑,而且漂移量都远小于LOAM。使用VLP16采一圈回到原点之后LOAM平移量飘了56.8cm(0.27%),而BALM飘了28cm(0.13%)
- 运行速度:在结合了BALM的LOAM框架中,主要得益于不需要建KD树去搜索五个最近邻,结合了BALM的LOAM表现出了较好的实时性。当然我理解这个运行速度只是使用了自适应体素特征,以及前后端线程共享内存的操作取代了原本建KD树搜索最近邻带来的增益,实际上基于非线性优化的后端难免还是要比基于滤波器的后端实时性要差一些的。
7 算法应用场景解析
由实际应用看下来这个算法存在以下特性:
- 适应多种雷达:不管你是机械式还是固态,不管是16线还是128线,得益于自适应体素化的特征提取方法,全都可以在一个框架下完成特征提取与对应
- 场景要求更高:如果连线面特征都提取不出来,场景给的约束可能会不够充分
- 实时性略差:相对基于滤波的后端要差一些。比如一不当心某个特征体素内点云太多了,Hessian矩阵就会有很高的维数,求解非线性优化步的耗时就会很长
因此除了作为SLAM的后端,这个算法一个很适合的应用是搞激光雷达外参标定:不管是雷达到车体(opencalib[5]的雷达到车体自标定[9]有借鉴这个思想),还是多激光联合标定[3],都已经有行之有效的论文和开源代码。吃场景和缺乏实时性对于传感器标定的业务来说,是不值得一提的弱点:一般标定不会跟智驾同时运行,可以有充分的算力,而且可以对场景提出要求。此外这个算法还有新的一代BALM2 [2][7],其最大的亮点是引入了PointCluster的概念,加快了计算速度,并且能计算当前位姿的uncertainty,还围绕这个概念设计了一套完备的理论。但是其实BALM1对于离线SLAM应用来说已经效果非常不错了。
相关文章:
SLAM论文详解(5) — Bundle_Adjustment_LM(BALM)论文详解
目录 1 摘要 2 相关工作 3 BA公式和导数 A. 直接BA公式 B. 导数 C. 二阶近似 4 自适应体素化 5. 将BALM结合进LOAM 6. 实验 7. 算法应用场景解析 1 摘要 Bundle Adjustment是一种用于同时估计三维结构和传感器运动运动的优化算法。在视觉SLAM,三维重建等…...
C语言对单链表所有操作与一些相关面试题
目录 单链表的特性 单链表的所有操作 定义一个单链表 创建一个链表头 插入数据(头插法) 插入数据(尾插法) 查找节点 修改数据节点 删除节点 打印数据 销毁链表 翻转链表 打印链表长度 冒泡排序 快排 堆排 查找倒数第K个节点(双指针法) …...
高防服务器如何抵御大规模攻击
高防服务器如何抵御大规模攻击?高防服务器是一种专门设计用于抵御大规模攻击的服务器,具备出色的安全性和可靠性。在当今互联网时代,网络安全问题日益严重,DDOS攻击(分布式拒绝服务攻击)等高强度攻击已成为…...
Go 接口和多态
在讲解具体的接口之前,先看如下问题。 使用面向对象的方式,设计一个加减的计算器 代码如下: package mainimport "fmt"//父类,这是结构体 type Operate struct {num1 intnum2 int }//加法子类,这是结构体…...
Git忽略文件的几种方法,以及.gitignore文件的忽略规则
目录 .gitignore文件Git忽略规则以及优先级.gitignore文件忽略规则常用匹配示例: 有三种方法可以实现忽略Git中不想提交的文件。1、在Git项目中定义 .gitignore 文件(优先级最高,推荐!)2、在Git项目的设置中指定排除文…...
C语言——指针进阶(2)
继续上次的指针,想起来还有指针的内容还没有更新完,今天来补上之前的内容,上次我们讲了函数指针,并且使用它来实现一些功能,今天我们就讲一讲函数指针数组等内容,废话不多说,我们开始今天的学习…...
【汇编中的寄存器分类与不同寄存器的用途】
汇编中的寄存器分类与不同寄存器的用途 寄存器分类 在计算机体系结构中,8086CPU,寄存器可以分为以下几类: 1. 通用寄存器: 通用寄存器是用于存储数据和执行算术运算的寄存器。在 x86 架构中,这些通用寄存器通常包括…...
基于文本提示的图像目标检测与分割实践
近年来,计算机视觉取得了显着的进步,特别是在图像分割和目标检测任务方面。 最近值得注意的突破之一是分段任意模型(SAM),这是一种多功能深度学习模型,旨在有效地从图像和输入提示中预测对象掩模。 通过利用…...
【4-5章】Spark编程基础(Python版)
课程资源:(林子雨)Spark编程基础(Python版)_哔哩哔哩_bilibili 第4章 RDD编程(21节) Spark生态系统: Spark Core:底层核心(RDD编程是针对这个)Spark SQL:…...
04 卷积神经网络搭建
一、数据集 MNIST数据集是从NIST的两个手写数字数据集:Special Database 3 和Special Database 1中分别取出部分图像,并经过一些图像处理后得到的[参考]。 MNIST数据集共有70000张图像,其中训练集60000张,测试集10000张。所有图…...
【hadoop运维】running beyond physical memory limits:正确配置yarn中的mapreduce内存
文章目录 一. 问题描述二. 问题分析与解决1. container内存监控1.1. 虚拟内存判断1.2. 物理内存判断 2. 正确配置mapReduce内存2.1. 配置map和reduce进程的物理内存:2.2. Map 和Reduce 进程的JVM 堆大小 3. 小结 一. 问题描述 在hadoop3.0.3集群上执行hive3.1.2的任…...
数据结构--6.5二叉排序树(插入,查找和删除)
目录 一、创建 二、插入 三、删除 二叉排序树(Binary Sort Tree)又称为二叉查找树,它或者是一棵空树,或者是具有下列性质的二叉树: ——若它的左子树不为空,则左子树上所有结点的值均小于它的根结构的值…...
无需公网IP,在家SSH远程连接公司内网服务器「cpolar内网穿透」
文章目录 1. Linux CentOS安装cpolar2. 创建TCP隧道3. 随机地址公网远程连接4. 固定TCP地址5. 使用固定公网TCP地址SSH远程 本次教程我们来实现如何在外公网环境下,SSH远程连接家里/公司的Linux CentOS服务器,无需公网IP,也不需要设置路由器。…...
Java工具类
一、org.apache.commons.io.IOUtils closeQuietly() toString() copy() toByteArray() write() toInputStream() readLines() copyLarge() lineIterator() readFully() 二、org.apache.commons.io.FileUtils deleteDirectory() readFileToString() de…...
makefile之使用函数wildcard和patsubst
Makefile之调用函数 调用makefile机制实现的一些函数 $(function arguments) : function是函数名,arguments是该函数的参数 参数和函数名用空格或Tab分隔,如果有多个参数,之间用逗号隔开. wildcard函数:让通配符在makefile文件中使用有效果 $(wildcard pattern) 输入只有一个参…...
算法通关村第十八关——排列问题
LeetCode46.给定一个没有重复数字的序列,返回其所有可能的全排列。例如: 输入:[1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 元素1在[1,2]中已经使…...
基于STM32设计的生理监测装置
一、项目功能要求 设计并制作一个生理监测装置,能够实时监测人体的心电图、呼吸和温度,并在LCD液晶显示屏上显示相关数据。 随着现代生活节奏的加快和环境的变化,人们对身体健康的关注程度越来越高。为了及时掌握自身的生理状况,…...
Go-Python-Java-C-LeetCode高分解法-第五周合集
前言 本题解Go语言部分基于 LeetCode-Go 其他部分基于本人实践学习 个人题解GitHub连接:LeetCode-Go-Python-Java-C Go-Python-Java-C-LeetCode高分解法-第一周合集 Go-Python-Java-C-LeetCode高分解法-第二周合集 Go-Python-Java-C-LeetCode高分解法-第三周合集 G…...
【前端知识】前端加密算法(base64、md5、sha1、escape/unescape、AES/DES)
前端加密算法 一、base64加解密算法 简介:Base64算法使用64个字符(A-Z、a-z、0-9、、/)来表示二进制数据的64种可能性,将每3个字节的数据编码为4个可打印字符。如果字节数不是3的倍数,将会进行填充。 优点࿱…...
leetcode 925. 长按键入
2023.9.7 我的基本思路是两数组字符逐一对比,遇到不同的字符,判断一下typed与上一字符是否相同,不相同返回false,相同则继续对比。 最后要分别判断name和typed分别先遍历完时的情况。直接看代码: class Solution { p…...
[CMake教程] 循环
目录 一、foreach()二、while()三、break() 与 continue() 作为一个编程语言,CMake也少不了循环流程控制,他提供两种循环foreach() 和 while()。 一、foreach() 基本语法: foreach(<loop_var> <items>)<commands> endfo…...
Mojo安装使用初体验
一个声称比python块68000倍的语言 蹭个热度,安装试试 系统配置要求: 不支持Windows系统 配置要求: 系统:Ubuntu 20.04/22.04 LTSCPU:x86-64 CPU (with SSE4.2 or newer)内存:8 GiB memoryPython 3.8 - 3.10g or cla…...
艺术与AI:科技与艺术的完美融合
文章目录 艺术创作的新工具生成艺术艺术与数据 AI与互动艺术虚拟现实(VR)与增强现实(AR)机器学习与互动性 艺术与AI的伦理问题结语 🎉欢迎来到AIGC人工智能专栏~艺术与AI:科技与艺术的完美融合 ☆* o(≧▽≦…...
Android常用的工具“小插件”——Widget机制
Widget俗称“小插件”,是Android系统中一个很常用的工具。比如我们可以在Launcher中添加一个音乐播放器的Widget。 在Launcher上可以添加插件,那么是不是说只有Launcher才具备这个功能呢? Android系统并没有具体规定谁才能充当“Widget容器…...
探索在云原生环境中构建的大数据驱动的智能应用程序的成功案例,并分析它们的关键要素。
文章目录 1. Netflix - 个性化推荐引擎2. Uber - 实时数据分析和决策支持3. Airbnb - 价格预测和优化5. Google - 自然语言处理和搜索优化 🎈个人主页:程序员 小侯 🎐CSDN新晋作者 🎉欢迎 👍点赞✍评论⭐收藏 ✨收录专…...
jupyter 添加中文选项
文章目录 jupyter 添加中文选项1. 下载中文包2. 选择中文重新加载一下,页面就变成中文了 jupyter 添加中文选项 1. 下载中文包 pip install jupyterlab-language-pack-zh-CN2. 选择中文 重新加载一下,页面就变成中文了 这才是设置中文的正解ÿ…...
系列十、Java操作RocketMQ之批量消息
一、概述 RocketMQ可以一次性发送一组消息,那么这一组消息会被当做一个消息进行消费。 二、案例代码 2.1、pom 同系列五 2.2、RocketMQConstant 同系列五 2.3、BatchConsumer package org.star.batch.consumer;import cn.hutool.core.util.StrUtil; import lom…...
leetcode1两数之和
题目: 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你…...
近年GDC服务器分享合集(四): 《火箭联盟》:为免费游玩而进行的扩展
如今,网络游戏采用免费游玩(Free to Play)加内购的比例要远大于买断制,这是因为前者能带来更低的用户门槛。甚至有游戏为了获取更多的用户,选择把原来的买断制改为免费游玩,一个典型的例子就是最近的网易的…...
android反射详解
1,反射的定义 一般情况下,我们使用某个类时必定知道它是什么类,是用来做什么的,并且能够获得此类的引用。于是我们直接对这个类进行实例化,之后使用这个类对象进行操作。 反射则是一开始并不知道我要初始化的类对象是…...
湖南电子科技网站建设/百度站长工具
linux采用scp命令拷贝文件到本地,拷贝本地文件到远程服务器 // 假设远程服务器IP地址为 192.168.1.100 1.从服务器复制文件到本地: scp root192.168.1.100:/data/test.txt /home/myfile/ root192.168.1.100 root是目标服务器(有你需要拷…...
做招聘的h5用哪个网站/软文广告文案案例
遇到情况: 预览小程序时,提示 “Error: 代码包大小为 2491 kb,上限为 2048 kb请删除文件后重试” 看了一下官方说明如下: 目前小程序分包大小有以下限制: 解决方案: 对小程序进行分包,可以优…...
wordpress邮件发送不出去/永久免费低代码开发平台
集合 1.集合Collection是Java JDK提供的一个工具类,用于存储任意数量具有相同属性的对象。一个Collection就是一个Object,包含这个对象中的所有元素。 如下所示,Collection提供了一个根接口,Set和List都继承Collection接口&#…...
做网站赚广告费多么/百度网盘24小时人工电话
好久没有写博文了呀呀呀........博客园的MarkDown还是...算了吧 自定义 Restful 风格结果集 参考资料 【SpringBoot专题】统一异常处理和统一数据返回前言实践运行结果 如果不了解泛型,请看:Java泛型详解:<T>和Class<T>的使用。泛…...
能免费做微信群推广的网站/网站排名推广推荐
最近在用Spark同步数据的时候想到,是否可以直接从已有的OBIEE读取数据,OBIEE上面有完整的语义层,读取数据就比较方便了.我先测试了 10.1.3.4.1的版本,jdbc位置在$obieefolder/OracleBI/jdbc/bijdbc.jar可以使用以下命令测试java -classpath $obieefolder/OracleBI/j…...
青州市建设局网站/上海网站建设
原文http://realtcg.com/2018/03/17/react-source-code-analysis-2-initial-render/ 上一篇文章讲到了React 调用ReactDOM.render首次渲染组件的前几个过程的源码, 包括创建元素、根据元素实例化对应组件, 利用事务来进行批量更新. 我们还穿插介绍了React 事务的实现以及如何利…...