视觉SLAM学习打卡【10】-后端·滑动窗口法位姿图

  • 本节是对上一节BA的进一步简化,旨在提高优化实时性.
  • 难点在于位姿图部分的雅可比矩阵求解(涉及李代数扰动模型求导),书中的相关推导存在跳步(可能数学功底强的人认为过渡的理所当然),笔者参考了知乎Clark的推导,并以顺向思维的方式重新整理推导过程,使得该部分更加通俗易懂.

视觉SLAM学习打卡【10】-后端·滑动窗口法&位姿图

  • 一、本讲缘由
  • 二、滑动窗口法
    • (1)某个时刻窗口的优化处理
    • (2)窗口滑动,结构发生改变
  • 三、位姿图
  • 四、实践g2o_viewer报错解决方案

一、本讲缘由

接上节 视觉SLAM学习打卡【9】-后端·卡尔曼滤波器&光束法平差,BA能同时优化位姿与空间点。然而,大量的路标点/特征点,使得计算量增大,实时性降低。本讲致力于控制BA的规模

  • 滑动窗口法(Sliding Window):将BA控制在一个时间窗口中,离开窗口的关键帧被丢弃.
  • 共视图(Covisibility graph):与当前相机存在共同观测的关键帧构成的图像即为共视图。仅优化与当前帧有20个以上共视路标的关键帧,其余固定不变.请添加图片描述
  • 位姿图(Pose Graph):不管路标,只管轨迹,构建一个只有轨迹的图优化.

二、滑动窗口法

仅保留离当前时刻最近的 N个关键帧(从连续视频中抽出的一部分图像),去掉时间上最早的关键帧。于是BA被固定在一个时间窗口内,离开这个窗口则被丢弃,这种方法称为滑动窗口法

(1)某个时刻窗口的优化处理

假设此时这个窗口内有 N 个关键帧和M个路标点.

  • 关键帧位姿表达为: x 1 , ⋯   , x N x_1,\cdots,x_N x1,,xN
  • 路标点为: y 1 , ⋯   , y M y_1,\cdots,y_M y1,,yM

用上一讲BA方法处理这个滑动窗口,包括建立最小二乘问题,构建整体的Hessian海森矩阵,然后边缘化所有路标点来加速求解。

最后,优化结果为: [ x 1 , ⋯   , x N ] T ∼ N ( [ μ 1 , ⋯   , μ N ] T , Σ ) [x_1,\cdots,x_N]^T\sim N([\mu_1,\cdots,\mu_N]^T,\Sigma) [x1,,xN]TN([μ1,,μN]T,Σ)

其中,均值部分 μ k \mu_{k} μk为为第 k个关键帧的位姿均值,即BA迭代之后的结果;所有关键帧的协方差矩阵 Σ \Sigma Σ是对整个 BA 的 H 矩阵进行舒尔消元边缘化后的系数矩阵.

(2)窗口滑动,结构发生改变

滑动中,状态变量的更新讨论:

  • 新增一个关键帧和对应观测到的路标点
    类似于(1),BA (N+1) 个关键帧和对应的路标点.
  • 删除 / 边缘化一个旧的关键帧
    删除旧关键帧 x1,将 x1 边缘化之后将导致整个问题不再稀疏,将破坏路标部分的对角块结构.

当边缘化路标点时,S= [ B − E C − 1 E T 0 E T C ] \begin{bmatrix}B-EC^{-1}E^\mathrm{T}&0\\E^\mathrm{T}&C\end{bmatrix} [BEC1ETET0C],Fill-in将出现在左上角的位姿块中,右下角的路标块仍为对角阵,保持稀疏,不影响求解

当边缘化关键帧时,Fill-in将出现在右下角的路标块中,BA无法按照之前的稀疏方式迭代求解.

解决方法:边缘化关键帧的同时,边缘化它观测到的路标点,保持了右下角的对角块结构。在OKVIS中,根据要边缘化的关键帧所看到的路标点是否在最新的关键帧中能看到来考虑是否边缘化此路标点。如果不能,就直接边缘化这个路标点;如果能,就丢弃被边缘化关键帧对这个路标点的观测,从而保持BA的稀疏性。

三、位姿图

构建一个只有轨迹的图优化,而位姿节点之间的边,可以由两个关键帧之间通过特征匹配之后得到的运动估计来给定初值(对极几何 / PnP / ICP)。不同的是,一旦初始估计完成,就不再优化那些路标点的位置,而只关心所有的相机位姿之间的联系,省去了大量特征点优化的计算,只保留了关键帧的轨迹,从而构建了所谓的位姿图.请添加图片描述
图优化中,节点表示相机位姿,以 T 1 , ⋯   , T n T_1,\cdots,T_n T1,,Tn表示;是两个位姿节点之间相对运动的估计(特征点法/直接法/GPS / IMU积分)

GPS通过连续测量两个位姿节点在不同时间点的绝对位置,进而通过比较这些位置数据来间接估计它们之间的相对运动。

IMU积分通过测量和跟踪物体的加速度和角速度,并对其进行积分运算,从而估计出两个位姿节点之间的相对运动。

估计 T i T_{i} Ti T j T_{j} Tj之间的运动 Δ T i j \Delta T_{ij} ΔTij,李群写法: Δ T i j = T i − 1 T j ΔT_{ij}=T_i^{-1}T_j ΔTij=Ti1Tj李代数写法: Δ ξ i j = ξ i − 1 ∘ ξ j = ln ⁡ ( T i − 1 T j ) ∨ \Delta\xi_{ij}=\xi_i^{-1}\circ\xi_j=\ln(T_i^{-1}T_j)^\vee Δξij=ξi1ξj=ln(Ti1Tj)构建误差 e i j e_{ij} eij: e i j = ln ⁡ ( T i j − 1 T i − 1 T j ) ∨ = l n ( I ) = 0 e_{ij}=\ln(T_{ij}^{-1}T_i^{-1}T_j)^\vee= ln(I)=0 eij=ln(Tij1Ti1Tj)=ln(I)=0优化变量有两个 ξ i \xi_{i} ξi ξ j \xi_{j} ξj,求 e i j e_{ij} eij关于这两个变量的导数(利用扰动模型,给 ξ i \xi_{i} ξi ξ j \xi_{j} ξj各乘一个左扰动 δ ξ i \delta\xi_{i} δξi δ ξ j \delta\xi_{j} δξj): e ^ i j = ln ⁡ ( T i j − 1 T i − 1 exp ⁡ ( ( − δ ξ i ) ∧ ) exp ⁡ ( δ ξ j ∧ ) T j ) ∨ \hat{e}_{ij}=\ln(T_{ij}^{-1}T_i^{-1}\exp((-\delta\xi_i)^{\wedge})\exp(\delta\xi_j^{\wedge})T_j)^{\vee} e^ij=ln(Tij1Ti1exp((δξi))exp(δξj)Tj)

其中, δ ξ i \delta\xi_{i} δξi乘左扰动到了右边,是因为逆的存在 ( exp ⁡ ( δ ξ i ∧ ) T i ) − 1 = T i − 1 ⋅ ( exp ⁡ ( δ ξ i ∧ ) ) − 1 = T i − 1 ⋅ exp ⁡ ( − δ ξ i ∧ ) \begin{aligned}&(\exp(\delta\xi_{i}^{\wedge})T_{i})^{-1}\\&=T_{i}^{-1}\cdot(\exp(\delta\xi_{i}^{\wedge}))^{-1}\\&=T_{i}^{-1}\cdot \exp(-\delta\xi_{i}^{\wedge})\end{aligned} (exp(δξi)Ti)1=Ti1(exp(δξi))1=Ti1exp(δξi)

根据伴随性质公式 exp ⁡ ( ( A d ( T ) ξ ) ∧ ) = T exp ⁡ ( ξ ∧ ) T − 1 \exp((Ad(T)\xi)^{\wedge})=T\exp(\xi^{\wedge})T^{-1} exp((Ad(T)ξ))=Texp(ξ)T1 (其中, A d ( T ) = [ R t ∧ R 0 R ] Ad(T)=\begin{bmatrix}R&t^\wedge R\\\mathbf{0}&R\end{bmatrix} Ad(T)=[R0tRR])的变形 exp ⁡ ( ξ ∧ ) T = T exp ⁡ ( ( A d ( T − 1 ) ξ ) ∧ ) \exp(\xi^\wedge)T=T\exp((Ad(T^{-1})\xi)^\wedge) exp(ξ)T=Texp((Ad(T1)ξ)) ,把扰动项挪到最右边: e ^ i j = ln ⁡ ( T i j − 1 T i − 1 exp ⁡ ( ( − δ ξ i ) ∧ ) exp ⁡ ( δ ξ j ∧ ) T j ⏟ 伴随性质 ) ∨ = ln ⁡ ( T i j − 1 T i − 1 exp ⁡ ( ( − δ ξ i ) ∧ ) T j exp ⁡ ( ( A d ( T j − 1 ) δ ξ j ) ∧ ) ⏞ ) ∨ = ln ⁡ ( T i j − 1 T i − 1 exp ⁡ ( ( − δ ξ i ) ∧ ) T j ⏟ 伴随性质 exp ⁡ ( ( A d ( T j − 1 ) δ ξ j ) ∧ ) ∨ = ln ⁡ ( T i j − 1 T i − 1 T j exp ⁡ ( ( − A d ( T j − 1 ) δ ξ i ) ∧ ) ⏞ exp ⁡ ( ( A d ( T j − 1 ) δ ξ j ) ∧ ) ) ∨ \begin{aligned} \hat{e}_{ij}& =\ln\left(T_{ij}^{-1}T_{i}^{-1}\exp\left((-\delta\xi_{i})^{\wedge}\right)\underbrace{\exp(\delta\xi_{j}^{\wedge})T_{j}}_{\text{伴随性质}}\right)^{\vee} \\ &=\ln\left(T_{ij}^{-1}T_i^{-1}\exp((-\delta\xi_i)^\wedge)\overbrace{T_j\exp((Ad(T_j^{-1})\delta\xi_j)^\wedge)}\right)^\vee \\ &=\ln\left(T_{ij}^{-1}T_i^{-1}\underbrace{\exp\left((-\delta\xi_i)^\wedge\right)T_j}_\text{伴随性质}\exp\left((Ad(T_j^{-1})\delta\xi_j\right)^\wedge\right)^\vee \\ &=\ln\left(T_{ij}^{-1}T_i^{-1}\overbrace{T_j\exp\left(\left(-Ad(T_j^{-1})\delta\xi_i\right)^{\wedge}\right)}\exp\left(\left(Ad(T_j^{-1})\delta\xi_j\right)^{\wedge}\right)\right)^{\vee} \end{aligned} e^ij=ln Tij1Ti1exp((δξi))伴随性质 exp(δξj)Tj =ln(Tij1Ti1exp((δξi))Tjexp((Ad(Tj1)δξj)) )=ln Tij1Ti1伴随性质 exp((δξi))Tjexp((Ad(Tj1)δξj) =ln(Tij1Ti1Tjexp((Ad(Tj1)δξi)) exp((Ad(Tj1)δξj)))

对上述指数 exp ⁡ ( ( − A d ( T j − 1 ) δ ξ i ) ∧ ) \exp\left(\left(-Ad(T_j^{-1})\delta\xi_i\right)^\wedge\right) exp((Ad(Tj1)δξi)) exp ⁡ ( ( A d ( T j − 1 ) δ ξ j ) ∧ ) \exp\left(\left(Ad(T_j^{-1})\delta\xi_j\right)^\wedge\right) exp((Ad(Tj1)δξj))分别做泰勒一阶展开: exp ⁡ ( ( − A d ( T j − 1 ) δ ξ i ) ∧ ) = I + ( − A d ( T j − 1 ) δ ξ i ) ∧ exp ⁡ ( ( A d ( T j − 1 ) δ ξ j ) ∧ ) = I + ( A d ( T j − 1 ) δ ξ j ) ∧ \exp\left(\left(-Ad(T_j^{-1})\delta\xi_i\right)^\wedge\right)=I+\left(-Ad(T_j^{-1})\delta\xi_i\right)^\wedge\\\exp\left(\left(Ad(T_j^{-1})\delta\xi_j\right)^\wedge\right)=I+\left(Ad(T_j^{-1})\delta\xi_j\right)^\wedge exp((Ad(Tj1)δξi))=I+(Ad(Tj1)δξi)exp((Ad(Tj1)δξj))=I+(Ad(Tj1)δξj)忽略二次项得: exp ⁡ ( ( − A d ( T j − 1 ) δ ξ i ) ∧ ) exp ⁡ ( ( A d ( T j − 1 ) δ ξ j ) ∧ ) ≈ ( I + ( − A d ( T j − 1 ) δ ξ i ) ∧ ) ( I + ( A d ( T j − 1 ) δ ξ j ) ∧ ) ≈ I + ( − A d ( T j − 1 ) δ ξ i ) ∧ + ( A d ( T j − 1 ) δ ξ j ) ∧ + ( − A d ( T j − 1 ) δ ξ i ) ∧ ( A d ( T j − 1 ) δ ξ j ) ∧ ⏟ 二次项忽略不计 = I + ( − A d ( T j − 1 ) δ ξ i ) ∧ + ( A d ( T j − 1 ) δ ξ j ) ∧ \begin{aligned} \exp\left(\left(-Ad(T_{j}^{-1})\delta\xi_{i}\right)^{\wedge}\right)\exp\left(\left(Ad(T_{j}^{-1})\delta\xi_{j}\right)^{\wedge}\right)& \approx\left(I+\left(-Ad(T_{j}^{-1})\delta\xi_{i}\right)^{\wedge}\right)\left(I+\left(Ad(T_{j}^{-1})\delta\xi_{j}\right)^{\wedge}\right) \\ &\approx I+\left(-Ad(T_j^{-1})\delta\xi_i\right)^{\wedge}+\left(Ad(T_j^{-1})\delta\xi_j\right)^{\wedge} \\ &+\underbrace{{\left(-Ad(T_{j}^{-1})\delta\xi_{i}\right)^{\wedge}\left(Ad(T_{j}^{-1})\delta\xi_{j}\right)^{\wedge}}}_{\text{二次项忽略不计}} \\ &=I+\left(-Ad(T_j^{-1})\delta\xi_i\right)^{\wedge}+\left(Ad(T_j^{-1})\delta\xi_j\right)^{\wedge} \end{aligned} exp((Ad(Tj1)δξi))exp((Ad(Tj1)δξj))(I+(Ad(Tj1)δξi))(I+(Ad(Tj1)δξj))I+(Ad(Tj1)δξi)+(Ad(Tj1)δξj)+二次项忽略不计 (Ad(Tj1)δξi)(Ad(Tj1)δξj)=I+(Ad(Tj1)δξi)+(Ad(Tj1)δξj)

e ^ i j ≈ ln ⁡ ( T i j − 1 T i − 1 T j [ I + ( − A d ( T j − 1 ) δ ξ i ) ∧ + ( A d ( T j − 1 ) δ ξ j ) ∧ ] ) ∨ \hat{e}_{ij}\approx\ln\left(T_{ij}^{-1}T_i^{-1}T_j\left[I+\left(-Ad(T_j^{-1})\delta\xi_i\right)^\wedge+\left(Ad(T_j^{-1})\delta\xi_j\right)^\wedge\right]\right)^\vee e^ijln(Tij1Ti1Tj[I+(Ad(Tj1)δξi)+(Ad(Tj1)δξj)])

  • 令变换矩阵 T i j − 1 T i − 1 T j T_{ij}^{-1}T_i^{-1}T_j Tij1Ti1Tj对应的李代数为 e i j e_{ij} eij,根据李群李代数的对应关系得: T i j − 1 T i − 1 T j = exp ⁡ ( e i j ∧ ) T_{ij}^{-1}T_i^{-1}T_j=\exp(e_{ij}^{\wedge}) Tij1Ti1Tj=exp(eij)
  • 再令 exp ⁡ ( x ∧ ) = I + ( − A d ( T j − 1 ) δ ξ i ) ∧ + ( A d ( T j − 1 ) δ ξ j ) ∧ \exp(x^\wedge)=I+\left(-Ad(T_j^{-1})\delta\xi_i\right)^\wedge+\left(Ad(T_j^{-1})\delta\xi_j\right)^\wedge exp(x)=I+(Ad(Tj1)δξi)+(Ad(Tj1)δξj)根据对数函数的泰勒展开式: ln ⁡ ( A ) = ( A − I ) − ( A − I ) 2 2 + ( A − I ) 3 3 − … \ln(A)=(A-I)-\frac{(A-I)^2}2+\frac{(A-I)^3}3-\ldots ln(A)=(AI)2(AI)2+3(AI)3取其中的一阶项,可得: x ∧ = ln ⁡ ( I + ( − A d ( T j − 1 ) δ ξ i ) ∧ + ( A d ( T j − 1 ) δ ξ j ) ∧ ) ≈ I + ( − A d ( T j − 1 ) δ ξ i ) ∧ + ( A d ( T j − 1 ) δ ξ j ) ∧ − I = − ( A d ( T j − 1 ) δ ξ i ) ∧ + ( A d ( T j − 1 ) δ ξ j ) ∧ \begin{aligned} x^{\wedge}& =\ln\left(I+\left(-Ad(T_j^{-1})\delta\xi_i\right)^\wedge+\left(Ad(T_j^{-1})\delta\xi_j\right)^\wedge\right) \\ &\approx I+\left(-Ad(T_j^{-1})\delta\xi_i\right)^\wedge+\left(Ad(T_j^{-1})\delta\xi_j\right)^\wedge-I \\ &=-\left(Ad(T_j^{-1})\delta\xi_i\right)^{\wedge}+\left(Ad(T_j^{-1})\delta\xi_j\right)^{\wedge} \end{aligned} x=ln(I+(Ad(Tj1)δξi)+(Ad(Tj1)δξj))I+(Ad(Tj1)δξi)+(Ad(Tj1)δξj)I=(Ad(Tj1)δξi)+(Ad(Tj1)δξj)

e ^ i j = ln ⁡ ( T i j − 1 T i − 1 T j [ I + ( − A d ( T j − 1 ) δ ξ i ) ∧ + ( A d ( T j − 1 ) δ ξ j ) ∧ ] ) ∨ = ln ⁡ ( exp ⁡ ( e i j ∧ ) exp ⁡ ( x ∧ ) ) ∨ \begin{aligned} \hat{e}_{ij}& =\ln\left(T_{ij}^{-1}T_i^{-1}T_j\left[I+\left(-Ad(T_j^{-1})\delta\xi_i\right)^\wedge+\left(Ad(T_j^{-1})\delta\xi_j\right)^\wedge\right]\right)^\vee \\ &=\ln\left(\exp(e_{ij}^{\wedge})\exp(x^{\wedge})\right)^{\vee} \end{aligned} e^ij=ln(Tij1Ti1Tj[I+(Ad(Tj1)δξi)+(Ad(Tj1)δξj)])=ln(exp(eij)exp(x))因此根据BCH的右乘近似公式可得(x为小量): e ^ i j = ln ⁡ ( exp ⁡ ( e i j ∧ ) exp ⁡ ( x ∧ ) ) ∨ = J r − 1 ( e i j ) x + e i j \hat{e}_{ij}=\ln\left(\exp(e_{ij}^{\wedge})\exp(x^{\wedge})\right)^{\vee}=\mathcal{J}_r^{-1}(e_{ij})x+e_{ij} e^ij=ln(exp(eij)exp(x))=Jr1(eij)x+eij ≈ J r − 1 ( e i j ) ( − A d ( T j − 1 ) δ ξ i + A d ( T j − 1 ) δ ξ j ) + e i j = e i j + ( − J r − 1 ( e i j ) A d ( T j − 1 ) ) ⏟ ∂ e i j ∂ δ ξ i δ ξ i + J r − 1 ( e i j ) A d ( T j − 1 ) ⏟ ∂ e i j ∂ δ ξ j δ ξ j \begin{aligned} &\approx\mathcal{J}_r^{-1}(e_{ij})\left(-Ad(T_j^{-1})\delta\xi_i+Ad(T_j^{-1})\delta\xi_j\right)+e_{ij} \\ &=e_{ij}+\underbrace{\left(-\mathcal{J}_r^{-1}(e_{ij})Ad(T_j^{-1})\right)}_{\frac{\partial e_{ij}}{\partial\delta\xi_i}}\delta\xi_i+\underbrace{\mathcal{J}_r^{-1}(e_{ij})Ad(T_j^{-1})}_{\frac{\partial e_{ij}}{\partial\delta\xi_j}}\delta\xi_j \end{aligned} Jr1(eij)(Ad(Tj1)δξi+Ad(Tj1)δξj)+eij=eij+δξieij (Jr1(eij)Ad(Tj1))δξi+δξjeij Jr1(eij)Ad(Tj1)δξj其中,为方便计算, J r − 1 ( e i j ) ≈ I + 1 2 [ ϕ e ∧ ρ e ∧ 0 ϕ e ∧ ] \left.\mathcal{J}_r^{-1}(e_{ij})\approx I+\frac{1}{2}\left[\begin{array}{cc}\phi_e^\wedge&\rho_e^\wedge\\\mathbf{0}&\phi_e^\wedge\end{array}\right.\right] Jr1(eij)I+21[ϕe0ρeϕe]或者 ≈ I \approx I I
通过 ∂ e i j ∂ δ ξ i = 0 \frac{\partial e_{ij}}{\partial\delta\xi_i}=0 δξieij=0 ∂ e i j ∂ δ ξ j = 0 \frac{\partial e_{ij}}{\partial\delta\xi_j}=0 δξjeij=0 求得 δ ξ i \delta\xi_{i} δξi δ ξ j \delta\xi_{j} δξj不断迭代 ξ i \xi_{i} ξi ξ j \xi_{j} ξj。求得目标函数 min ⁡ 1 2 ∑ i , j ∈ E e i j T Σ i j − 1 e i j \min\frac12\sum_{i,j\in\mathcal{E}}e_{ij}^T\Sigma_{ij}^{-1}e_{ij} min21i,jEeijTΣij1eij的最小值。

四、实践g2o_viewer报错解决方案

问题1

g2o_viewer: command not found

原因

之前编译g2o库的时候因为少装了部分依赖所以没有编译出 g2o_viewer的可执行文件

解决方案

补充下述依赖

sudo apt-get install libsuitesparse-dev qtdeclarative5-dev qt5-qmake
sudo apt-get install libqglviewer-dev-qt5

进入g2o的build文件夹下

cmake ..
make
sudo make install

问题2

g2o_viewer: error while loading shared libraries: libg2o_viewer.so: cannot o

解决方案

sudo ldconfig

sudo ldconfig命令的作用是确保新安装的动态链接库能够被系统正确识别和共享

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

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

相关文章

ELK企业级日志分析系统以及多种部署

目录 ELK简介 ELK简介 ELK平台是一套完整的日志集中处理解决方案,将 ElasticSearch、Logstash 和 Kiabana 三个开源工具配合使用, 完成更强大的用户对日志的查询、排序、统计需求。 ●ElasticSearch:是基于Lucene(一个全文检索引…

Command开源AI的未来

在AI的浩瀚宇宙中,有一个新星正在闪耀——Command R。这个开源的大型语言模型不仅在技术排行榜上名列前茅,更以其开放性和高性能赢得了全球开发者的关注和喜爱。 开源精神的胜利 Command R是由CohereAI推出的一款开源大语言模型,拥有1040亿…

CTFshow电子取证——内存取证2

接上回 JiaJia-CP-2 2.佳佳在网页上登录了自己的邮箱,请问佳佳的邮箱是? 因为是在网页上登陆的邮箱 用iehistory插件 查看一下网页历史记录 为了方便分析,使用grep命令正则匹配一下 **com 的记录 vol.py -f JiaJia_Co.raw --profileWin…

线程池-异步编排-完成时回调-线程串行化

上图中用exceptionally可以感知异常也可以处理返回结果 同时 我们使用handle也可以做到这种情况 线程串行化

IDEA Warnings:SQL dialect is not configured.

springboot项目XxxMapper.xml文件打开后显示warnings:SQL dialect is not configured......(翻译:未配置SQL语言。) 大概意思是没有在IDEA中配置当前sql是MySQl、Oracle还是MariaDB等语言。 配置一下就好: 完了&#…

synchronized底层原理

1synchronized关键字的底层原理 Monitor 举个例子: 1.线程1执行synchronized代码块,里面用到了lock(对象锁)。首先会让这个lock对象和monitor关联,判断monitor中的owner属性是否为null。如果为null直接获取对象锁。owner只能关联一个线程。 2…

node.js学习笔记(一):什么是node.js、fs 文件系统模块、path 路径模块、综合案例 - 时钟案例

目录 一、初识Node.js 1. 1.什么是 Node.js 1.2.Node.js 中的 JavaScript 运行环境 1.3. Node.js 可以做什么 1.4. Node.js 环境的安装 1.5. 在 Node.js 环境中执行 JavaScript 代码 二、fs 文件系统模块 2.1 什么是 fs 文件系统模块 2.2 读取指定文件中的内容 2.3 向…

牛顿-欧拉递推动力学方程①

文章目录 力和力矩的递推算式1 第i个连杆的静力平衡方程2 第i个连杆的动力平衡方程(不计重力)牛顿—欧拉递推动力学算法向外递推计算连杆的速度和加速度向内递推计算力和力矩计及重力的牛顿—欧拉动力学算法牛顿—欧拉动力学方程是应用达朗伯原理将动力学问题转化为牛顿—欧拉…

解决vue3更新chunk包后,点击页面报错

出现错误 解决思路 试了好多方法,跳了很多坑,router版本对不上,解决方案不实用。最后我直接捕获异常,刷新页面,解决最快最有效。 // vue-rotuer版本 "vue-router": "^4.0.3"解决方案 在router/…

Java基础-知识点03(面试|学习)

Java基础-知识点03 String类String类的作用及特性String不可以改变的原因及好处String、StringBuilder、StringBuffer的区别String中的replace和replaceAll的区别字符串拼接使用还是使用StringbuilderString中的equal()与Object方法中equals()区别String a new String("a…

springboot+ssm+java医生绩效管理系统

框架:SSM/springboot都有 jdk版本:1.8 及以上 ide工具:IDEA 或者eclipse 数据库: mysql 编程语言: java 前端:layuibootstrapjsp 详细技术:HTMLCSSJSjspspringmvcmybatisMYSQLMAVENtomcat 开发工具 IntelliJ IDEA: …

lanqiao.602 迷宫

题目&#xff1a; 代码&#xff1a; #include<iostream> #include<cstring> #include<algorithm> #include<queue> using namespace std; char mp[31][51]; //稍微开大一点 char k[4]{D,L,R,U}; //按字典序记录路径 int dirx[]{1,0,0,-1},d…

数模 初见数建

文章目录 初见数学建模1.1 数学建模是什么1.2 数学建模的概述1.3 如何学习数学建模---分模块化1.4 数学建模前提了解1.5 数学建模的六个步骤1.6 如何备战建模比赛1.7 数学建模赛题类型1.8 数学建模算法体系概述 初见数学建模 1.1 数学建模是什么 1.原型与模型 原型&#xff…

虚幻引擎架构自动化及蓝图编辑器高级开发进修班

课程名称&#xff1a;虚幻引擎架构自动化及蓝图编辑器高级开发进修班 课程介绍 大家好 我们即将推出一套课程 自动化系统开发。 自动化技术在项目开发的前中后期都大量运用。如何您是一家游戏公司&#xff0c;做的是网络游戏&#xff0c;是不是经常会遇到程序员打包加部署需…

RedisTemplate对象中方法的使用

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站&#xff0c;这篇文章男女通用&#xff0c;看懂了就去分享给你的码吧。 Redis是一个key-va…

【Java探索之旅】方法重载 递归

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; Java编程秘籍 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一、方法重载1.1 为什么要有方法重载1.2 方法重载的概念与使用1.3 方法签名 二、递归2…

车机系统与Android的关系

前言&#xff1a;搞懂 Android 系统和汽车到底有什么关系。 文章目录 一、基本概念1、Android Auto1&#xff09;是什么2&#xff09;功能 2、Google Assistant3、Android Automotive1、Android Auto 和 Android Automotive 的区别 4、App1&#xff09;App 的开发2&#xff09;…

【生产案例面试题】JVM调优

写作目的 最近上线了一个需求&#xff0c;遇到了一个JVM报警的问题&#xff0c;很荣幸能遇到&#xff0c;在此分享一下整个调优的过程。 背景 我们是中台服务&#xff0c;我们的甲方就是上游不同的业务。中台原则上是业务和能力分离&#xff0c;但是不可避免的是分不开&…

网络通信三要素:IP、端口和协议

IP&#xff1a;设备在网络中的地址&#xff0c;是唯一的标识 IP&#xff1a;全程”互联网协议地址“&#xff0c;是分配给上网设备的唯一标志 IP地址有两种形式&#xff1a; IPv4&#xff1a;32位 IPv6&#xff1a;共128位。分成8段表示&#xff0c;每取四位编码成一个16进制…

全新付费进群系统源码 带定位完整版 附教程

搭建教程 Nginx1.2 PHP5.6-7.2均可 最好是7.2 第一步上传文件程序到网站根目录解压 第二步导入数据库&#xff08;dkewl.sql&#xff09; 第三步修改/config/database.php里面的数据库地址 第四步修改/config/extra/ip.php里面的域名 第四步设置伪静态thinkphp 总后台账…