VINS初始化原理及代码

文章目录

    • 预备
      • 符号定义
      • 代码中常用的容器:
    • 初始化原理及步骤
      • 初始化目的
      • 初始化原理
      • 初始化步骤
    • 初始化详细流程、原理及代码。
    • 参考文献

预备

符号定义

( ⋅ ) w \left(\cdot\right)^w ()w表示世界坐标系下的表示,Z轴与重力方向重合。
( ⋅ ) b \left(\cdot\right)^b ()b表示体坐标系下的表示,与IMU坐标系绑定。
( ⋅ ) c \left(\cdot\right)^c ()c表示相机坐标系下的表示。
q b w q_b^w qbw p b w p_b^w pbw分别表示imu 体坐标系下转换到世界坐标系下对应的旋转和平移。
q c b q_c^b qcb p c b p_c^b pcb分别表示相机坐标系下转换到体坐标系下对应的旋转和平移。
( ⋅ ) b k \left(\cdot\right)^{b_k} ()bk 表示第k帧图像对应的体坐标系。
( ⋅ ) c k \left(\cdot\right)^{c_k} ()ck 表示第k帧图像对应的体坐标系。
( ⋅ ^ ) \left(\hat{\cdot}\right) (^)表示带误差的观测值/估计值(带噪声)。
p ˉ . \bar{p}. pˉ.表示不带尺度的视觉位移估计量。

代码中常用的容器:

feature_buf存放feature_tracker_node.cpp发布的特征点信息
imu_buf存放imu_msg

measurements 中配套存放新图像帧特征点信息及其时间戳对应的IMU预积分数据。

IntegrationBase预积分结构体:
result_delta_q/p/v指中值预积分;
jacobian存放预积分变量的雅可比
covariance协方差矩阵。

map<int, vector<pair<int, Eigen::Matrix<double, 7, 1>>>> image:帧特征点属性管理map
 每个特征点属性包括:(camera_id,[x,y,z,u,v,vx,vy]),索引为feature_id
xyz_uv_velocity << x, y, z, p_u, p_v, velocity_x, velocity_y;
image[feature_id].emplace_back(camera_id, xyz_uv_velocity);

all_image_frame存放所有图像帧数据(包含了特征点及IMU积分数据)。

f_manager存放管理特征点信息,包含各类特征点相关接口。

sfm_f统计各特征点在各帧中的观测。

pre_integrations 存放预积分量,与图像关键帧对应。

Estimator 为VIO结构体,包含各类接口及变量。

初始化原理及步骤

初始化目的

由于单目视觉的尺度信息缺失,采用IMU的位姿积分数据与通过视觉获得的位姿数据及逆行对比,从而估计出尺度信息,从而进一步得到所有特征点的坐标。
然而,完成IMU数据与相机数据的结合,需要知道相机坐标系与IMU坐标系之间的关系( q c b q_c^b qcb p c b p_c^b pcb),而此可以通过标定数据或者带IMU相机的工厂参数获得。
通常,相机与IMU之间的角度差异带来的影响较大,而其较小的位置差异对整个里程计的位置估计影响较小,因而,其位置差异 ( p c b ) (p_c^b) (pcb)可以被忽略。

此外,IMU数据存在零偏(零偏变化),加速度计中包含重力加速度。

初始化原理

初始化原理核心:
通过将相机视觉得到的角度信息与IMU角度信息对比,可以估计陀螺仪零偏,以及在线估计IMU与相机之间的角度差异。

通过将相机视觉得到的位置信息于IMU加速度积分的位置信息进行对比,从而估计出尺度信息,以及修正重力加速度。

初始化步骤

 预处理:
(1) 特征点提取。IMU预积分(基于IMU的时间戳)
(2) IMU与图像时间戳对齐与关联

 关联:
(3) (若无)则估计外参

 VINS初始化:
(4) (视觉)SFM求解。
(5) 视觉惯性对齐
     陀螺仪零偏估计
     尺度,重力加速度,速度计算

初始化详细流程、原理及代码。

 预处理:
(1)特征点提取;IMU预积分。
光流法提取跟踪特征点。IMU预积分(基于IMU的时间戳),二者分别运行于ROS两个node(feature_tracker_node.cppestimator_node.cpp

  1. 光流法提取跟踪特征点:feature_tracker_node.cpp
    核心函数:img_callback():readImage():
      createCLAHE->apply(): 首先对(太亮或太暗EQUALIZE=1)图像进行灰度直方图均衡化处理
      calcOpticalFlowPyrLK(): 使用LK光流法跟踪特征点
      outliers rejectWithF(): 通过基本矩阵剔除;
      setMask(): 设置mask保证提取特征点的均匀分布;
      goodFeaturesToTrack(): 查看是否需要提取特征点,并提取;
      undistortedPoints(): 对特征点坐标进行去畸变矫正,转换到归一化坐标系上,并计算每个角点的速度。
  2. IMU预积分:estimator_node.cppfactor/integration_base.h
    imu_callback():调用predict()发布高频PVQ,与IMU数据频率一致;
    核心函数:predict()通过中值积分计算当前时刻的PVQ,
    a ^ ˉ i ′ = 1 2 [ q ^ i ( a ^ i − b ^ a i ) + q ^ i + 1 ( a ^ i + 1 − b ^ a i ) ] {\bar {\hat a}_i}^\prime = \frac{1}{2}[{\hat q_i}({\hat a_i} - {\hat b_{{a_i}}}) + {\hat q_{i + 1}}({\hat a_{i + 1}} - {\hat b_{{a_i}}})] a^ˉi=21[q^i(a^ib^ai)+q^i+1(a^i+1b^ai)] ω ^ ˉ i ′ = 1 2 ( ω ^ i + ω ^ i + 1 ) − b ^ ω {\bar {\hat \omega}_i}^\prime = \frac{1}{2}({\hat \omega _i} + {\hat \omega _{i + 1}}) - {\hat b_\omega } ω^ˉi=21(ω^i+ω^i+1)b^ω
    在这里插入图片描述
    R ^ w b k p ^ b k + 1 w = R ^ w b k ( p ^ b k w + v ^ b k w Δ t k − 1 2 g w Δ t k 2 ) + α ^ b k + 1 b k R ^ w b k v ^ b k + 1 w = R ^ w b k ( v ^ b k w − g w Δ t k ) + β ^ b k + 1 b k q ^ w b k ⊗ q ^ b k + 1 w = γ ^ b k + 1 b k \begin{array}{} {\hat R_w^{{b_k}}\hat p_{{b_{k + 1}}}^w = \hat R_w^{{b_k}}\left( {\hat p_{{b_k}}^w + \hat v_{{b_k}}^w{\rm{\Delta }}{t_k} - \frac{1}{2}{g^w}{\rm{\Delta }}t_k^2} \right) + \hat \alpha _{{b_{k + 1}}}^{{b_k}}}\\ {\hat R_w^{{b_k}}\hat v_{{b_{k + 1}}}^w = \hat R_w^{{b_k}}(\hat v_{{b_k}}^w - {g^w}{\rm{\Delta }}{t_k}) + \hat \beta _{{b_{k + 1}}}^{{b_k}}}\\ {\hat q_w^{{b_k}} \otimes \hat q_{{b_{k + 1}}}^w = \hat \gamma _{{b_{k + 1}}}^{{b_k}}} \end{array} R^wbkp^bk+1w=R^wbk(p^bkw+v^bkwΔtk21gwΔtk2)+α^bk+1bkR^wbkv^bk+1w=R^wbk(v^bkwgwΔtk)+β^bk+1bkq^wbkq^bk+1w=γ^bk+1bk
    详细参见https://blog.csdn.net/weixin_41469272/article/details/138505746

步骤(2)及以后都对应estimator_node.cpp的代码,核心函数process()
imu_callback()feature_callback()分别打包imu预积分数据及特征点数据。并通过锁机制触发process()中的操作。

estimator_node.cpp: imu_callback()/feature_callback()/process()

process():VIO线程主函数
|–getMeasurements(): 搜集image及其时间戳附近的imu数据,打包存放到measurement。

|–estimator.processIMU():线性插值IMU数据,使之对齐图像时间戳。
  |–new IntegrationBase
  |–IntegrationBase->push_back(): propagate(): midPointIntegration() 中值积分,得到PVQ/协方差/雅可比

|–estimator.setReloFrame(): 重定位函数。

|–estimator.processImage(): 关键帧判定;外参标定;视觉惯性对齐;初始化等
  |–f_manager.addFeatureCheckParallax(): 判断是否为关键帧,选择marg帧。
  |–f_manager.getCorresponding(): 得到两帧的共视特征点。
  |–CalibrationExRotation():标定相机IMU外参。
    |–solveRelativeR(): 通过计算F阵解算R。

  |–initialStructure(): 初始化/初始化失败执行滑窗。
    |–relativePose(): 寻找滑窗中的枢纽帧。
    |–sfm.construct():求解滑窗口中的所有图像帧的位姿和特征点坐标。
      |–solveFrameByPnPPnP求解帧间位姿。
      |–triangulateTwoFrames(): 三角化特征点。
    |–visualInitialAlign()初始化核心函数,通过联合视觉IMU数据,求解尺度,重力,等等。
      |–VisualIMUAlignment: 计算陀螺仪偏置,尺度,重力加速度和速度。
        |–solveGyroscopeBias(): 陀螺仪零偏估计。
        |–LinearAlignment(): 尺度,重力加速度,速度计算。
          |–RefineGravity:固定重力幅值,进一步求解重力加速度及尺度等。

  |–slideWindow(): 滑窗计算。

|–update(): 获取滑动窗口当前图像帧的imu更新项[ P , Q , V , b a , b ω , a , g P,Q,V,b_a,b_\omega,a,g P,Q,V,ba,bω,a,g]; 更新imu_buf中的PVQ


|process() start-------------------------------------------------------------:

(2)IMU与图像时间戳对齐与关联

  1. 打包特征点数据及其前后发布的IMU积分数据
    核心函数getMeasurements()搜集image及其时间戳附近的imu数据,可出现以下两种情况:
    在这里插入图片描述
    对IMU数据进行线性插值,对齐图像帧。
    将新图像帧特征点信息及其时间戳对应的IMU预积分数据配套存放在measurements
    measurements 中配套存放新图像帧特征点信息及其时间戳对应的IMU预积分数据。

  2. IMU积分对齐图像时间戳(时间插值)
    核心函数estimator.processIMU() 计算imu数据与图像数据之间的时间差,利用中值积分及插值估算与图像帧时间戳对应的IMU积分值。
    processIMU():new IntegrationBase对象,并通过IntegrationBase->push_back->propagate->midPointIntegration()完成与图像帧对应的中值预积分(result_delta_q/p/v),以及预积分的雅可比(jacobian)及协方差矩阵(covariance)。

  3. 创建特征点特征管理器(map
    每个特征点属性包括:(camera_id,[x,y,z,u,v,vx,vy])s,索引为feature_id
     
    map<int, vector<pair<int, Eigen::Matrix<double, 7, 1>>>> image;
    xyz_uv_velocity << x, y, z, p_u, p_v, velocity_x, velocity_y;
    image[feature_id].emplace_back(camera_id, xyz_uv_velocity);


以下功能均在processImage()的函数内容:关键帧判定;外参标定;初始化;VIO等
all_image_frame存放所有图像帧数据(包含了特征点及IMU积分数据)
f_manager中存放管理特征点信息,包含各类特征点相关接口
f_manager.addFeatureCheckParallax()检测视差并选择添加关键帧


|processImage() start-------------------------------------------------------------:
 关联:

若需要估计外参,则估计外参 q c b q_c^b qcb; 首先通过f_manager.getCorresponding()得到两帧之间的共视点。
执行核心函数CalibrationExRotation():构建 A x = 0 Ax=0 Ax=0问题,使用SVD方法进行求解。

原理:联合视觉帧间角度估计(solveRelativeR()通过F矩阵计算得到)与IMU角度积分值(对应图像帧)得到。
q b k + 1 b k ⊗ q c b = q c b ⊗ q c k + 1 c k q_{b_{k+1}}^{b_k}\otimes q_c^b=q_c^b\otimes q_{c_{k+1}}^{c_k} qbk+1bkqcb=qcbqck+1ck
上式可写为
( [ q b k + 1 b k ] L − [ q c k + 1 c k ] R ) q c b = Q k + 1 k ⋅ q c b = 0 \left(\left[q_{b_{k+1}}^{b_k}\right]_L-\left[q_{c_{k+1}}^{c_k}\right]_R\right)q_c^b=Q_{k+1}^k\cdot q_c^b=0 ([qbk+1bk]L[qck+1ck]R)qcb=Qk+1kqcb=0
从而滑窗中的多组帧间约束,并利用鲁棒核函数构建问题:
[ w 1 0 ⋅ Q 1 0 w 2 1 ⋅ Q 2 1 ⋮ w N N − 1 ⋅ Q N N − 1 ] q c b = Q N ⋅ q c b = 0 \left[ {\begin{array}{} {w_1^0 \cdot Q_1^0}\\ {w_2^1 \cdot Q_2^1}\\ \vdots \\ {w_N^{N - 1} \cdot Q_N^{N - 1}} \end{array}} \right]q_c^b = {Q_N} \cdot q_c^b = 0 w10Q10w21Q21wNN1QNN1 qcb=QNqcb=0
其中鲁棒核函数权重:
w k + 1 k = { 1 , r k + 1 k < δ δ r k + 1 k , o t h e r w i s e w_{k + 1}^k = \left\{ {\begin{array}{} {1,}&{r_{k + 1}^k < \delta }\\ {\frac{\delta }{{r_{k + 1}^k}},}&{otherwise} \end{array}} \right. wk+1k={1,rk+1kδ,rk+1k<δotherwise
从而以上为 A X = 0 AX=0 AX=0的经典问题,可使用SVD方法进行求解,原理参考:https://blog.csdn.net/weixin_41469272/article/details/123696963

    |initialStructure() start---------------------------------------------------------:
 VINS初始化initialStructure()
(1)SFM求解

  1. 通过计算加速度的标准差,判断是否存在足够的偏移运动,从而使得三角化更加可信;

  2. 统计各特征点在各帧中的观测,存放在sfm_f中。

  3. 寻找滑窗中的最后一帧有足够视差的且足够多共视点的帧作为枢纽帧,与最后一帧完成三角化及PnP。核心函数relativePose():
    在这里插入图片描述五角星指选出的枢纽帧,遍历滑窗中的帧,计算其与滑窗最后一帧之间的视差和RT,当视差足够,且计算的RT对应的内点数足够时(solveRelativeRT=true)时,则认定该帧为枢纽帧。

  4. 通过上一步得到的特征点进一步使用SFM计算出滑窗中所有帧的位姿及特征点。
    核心函数sfm.construct():求解滑窗口中的所有图像帧的位姿和特征点坐标。
     
    首先设立枢纽帧的位姿为单位阵(以枢纽帧为原点进行三角化及PNP),叠加relativePose()的结果得到滑窗最后一帧的位姿;
     
    遍历滑窗内的帧(先从枢纽帧向后遍历,再向前遍历),分别三角化其与滑窗中最后一帧的共视特征点(triangulateTwoFrames()),及PNP求解该帧位姿(solveFrameByPnP());
    同时也三角化一下滑窗中相邻帧的之间的共视特征点。
    solveFrameByPnP调用cv::solvePnP函数实现;
    triangulateTwoFrames()采用构造 A X = 0 AX=0 AX=0,而后使用SVD方法实现三角化,原理见https://blog.csdn.net/weixin_41469272/article/details/123696963
     
    遍历所有帧(all_image_frame包括非滑窗帧),调用cv::solvePnP函数实现得到各帧的位姿。

(2)视觉惯性对齐visualInitialAlign()
核心函数VisualIMUAlignment()
      |VisualIMUAlignment start---------------------------------------------------------:

  1. 陀螺仪零偏估计solveGyroscopeBias()
    联合视觉帧间角度估计(上文SFM中得到)与IMU角度积分值(对应图像帧)得到。
    约束公式如下:
    在这里插入图片描述
    γ b k + 1 b k ≈ γ ^ b k + 1 b k ⊗ [ 1 1 2 J b ω γ δ b ω ] \gamma _{{b_{k + 1}}}^{{b_k}} \approx \hat \gamma _{{b_{k + 1}}}^{{b_k}} \otimes \left[ {\begin{array}{} 1\\ {\frac{1}{2}{\bf{J}}_{{b_\omega }}^\gamma \delta {{\bf{b}}_\omega }} \end{array}} \right] γbk+1bkγ^bk+1bk[121Jbωγδbω]
    其中:
    q b k + 1 c 0 − 1 ⊗ q b k c 0 ⊗ γ b k + 1 b k = q b k + 1 c 0 − 1 ⊗ q b k c 0 ⊗ γ ^ b k + 1 b k ⊗ [ 1 1 2 J b ω γ δ b ω ] = [ 1 0 ] {q_{b_{k+1}}^{c_0}}^{-1}\otimes q_{b_k}^{c_0}\otimes\gamma_{b_{k+1}}^{b_k}={q_{b_{k+1}}^{c_0}}^{-1}\otimes q_{b_k}^{c_0}\otimes\hat \gamma _{{b_{k + 1}}}^{{b_k}} \otimes \left[ {\begin{array}{} 1\\ {\frac{1}{2}{\bf{J}}_{{b_\omega }}^\gamma \delta {{\bf{b}}_\omega }} \end{array}} \right]=\left[\begin{matrix}1\\0\\\end{matrix}\right] qbk+1c01qbkc0γbk+1bk=qbk+1c01qbkc0γ^bk+1bk[121Jbωγδbω]=[10]
    [ 1 1 2 J b ω γ δ b ω ] = γ ^ b k + 1 b k − 1 ⊗ q b k c 0 − 1 ⊗ q b k + 1 c 0 = γ ^ b k + 1 b k − 1 ⊗ q b k + 1 b k \left[ {\begin{array}{} 1\\ {\frac{1}{2}{\bf{J}}_{{b_\omega }}^\gamma \delta {{\bf{b}}_\omega }} \end{array}} \right]={{\hat{\gamma}}_{b_{k+1}}^{b_k}}^{-1}\otimes{q_{b_k}^{c_0}}^{-1}\otimes q_{b_{k+1}}^{c_0}={{\hat{\gamma}}_{b_{k+1}}^{b_k}}^{-1}\otimes q_{b_{k+1}}^{b_k} [121Jbωγδbω]=γ^bk+1bk1qbkc01qbk+1c0=γ^bk+1bk1qbk+1bk
    只考虑虚部,从而得到AX=b的问题。
    在这里插入图片描述
    其中 J b w γ 为 γ b k + 1 b k J_{b_w}^\gamma为\gamma_{b_{k+1}}^{b_k} Jbwγγbk+1bk δ b w \delta b_w δbw的雅可比矩阵,作者从IntegrationBase对象的jacobian中截取。

  2. 尺度,重力加速度,速度计算LinearAlignment()
    通过对比加速度积分值与相机SFM得到的偏移,计算得到尺度,重力加速度,以及速度信息
    待求解变量:
    在这里插入图片描述
    约束公式如下:
    在这里插入图片描述
    通过整理上式,将待求解量提取出来,可将上式化为以下形式:
    在这里插入图片描述
    其中:
    在这里插入图片描述
    从而可构成最小二乘问题:在这里插入图片描述
    如此问题变为 A x = b Ax=b Ax=b的问题,使用x = A.ldlt().solve(b)进行求解。
     
    RefineGravity()通过固定重力加速度幅值,从而将重力加速度变为2维参数,再次对重力加速度进行优化。
    在这里插入图片描述
    图中: g ^ ˉ \bar{\hat{g}} g^ˉ表示经过上式得到的重力加速度的单位方向向量, ∣ g ∣ \left|g\right| g为指定的重力加速度的幅值,待求解 w 1 , w 2 w_1,w_2 w1,w2
    此时,待优化变量变为:
    在这里插入图片描述
    同时:
    在这里插入图片描述
    同样的方法进行求解Ax=b问题。
    VisualIMUAlignment--------------------------------------------------end|

  3. 得到重力加速度后,重新三角化及积分
    f_manager.triangulate()
    pre_integrations[i]->repropagate()

  4. 使用尺度信息恢复视觉偏移及特征点深度;

  5. 使世界坐标系z轴对齐重力加速度方向,并将特征点转换到世界坐标系下。


    initialStructure--------------------------------------------------end|

processImage--------------------------------------------------end|

process--------------------------------------------------end|

参考文献

《VINS 论文推导及代码解析 崔华坤》
《VINS-Mono: A Robust and Versatile Monocular Visual-Inertial State Estimator》
《Quaternion kinematics for the error-state Kalman filter》

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设置默认表空间和重命名

目录 设置默认表空间 创建的临时表空间 tspace4 修改为默认临时表空间 创建的永久性表空间 tspace3 修改为默认永久表空间 重命名表空间 将表空间 tspace3 修改为 tspace3_1 Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/13520…

动态规划——路径问题:931.下降路径最小和

文章目录 题目描述算法原理1.状态表示&#xff08;经验题目&#xff09;2.状态转移方程3.初始化4.填表顺序5.返回值 代码实现CJava 题目描述 题目链接&#xff1a;931.下降路径最小和 关于这⼀类题&#xff0c;看过我之前的博客的朋友对于状态表示以及状态转移是⽐较容易分析…

【CSS】认识CSS选择器及各选择器对应的用法

目录 一、什么是CSS&#xff1f; 二、CSS 选择器 1. 标签选择器 2. 类选择器 3. ID选择器 4. 通配符选择器 5. 复合选择器 一、什么是CSS&#xff1f; CSS(Cascading Style Sheet)&#xff0c;层叠样式表。它与 HTML&#xff08;超文本标记语言&#xff09;一起使用&am…

redis--安装

简介 官网&#xff1a;RedisInsight - The Best Redis GUI 各个版本官网下载地址&#xff1a;http://download.redis.io/releases/ Redis和Memcached是非关系型数据库也称为NoSQL数据库&#xff0c;MySQL、Mariadb、SQL Server、PostgreSQL Oracle 数据库属于关系型数据 应用…

[C++初阶]string的几道oj题

1.LCR 192. 把字符串转换成整数 (atoi) 这题难度不大,我这里采取遍历跳过空格的方式&#xff0c;我先展示出我的代码,然后慢慢讲解: class Solution { public:int myAtoi(string str) {if (str.empty()) return 0;int lengthstr.size();int i0;int symbol1;int sum0;while(i&l…

Apple强大功能:在新款 iPad Pro 和 iPad Air 中释放 M4 芯片潜力

Apple 的最新强大功能&#xff1a;在新款 iPad Pro 和 iPad Air 中释放 M4 芯片的潜力 概述 Apple 推出配备强大 M4 芯片的最新 iPad Pro 和 iPad Air 型号&#xff0c;再次突破创新界限。新一代 iPad 有望彻底改变我们的工作、创造和娱乐方式。凭借无与伦比的处理能力、令人惊…

QX-mini51单片机学习-----(3)流水灯

目录 1宏定义 2函数的定义 3延时函数 4标准库函数中的循环移位函数 5循环移位函数与左移和右移运算符的区别 6实例 7keil中DeBug的用法 1宏定义 是预处理语句不需要分号 #define uchar unsigned char//此时uchar代替unsigned char typedef是关键字 后面是接分号…

【maven】有些依赖的私有但构建老拉取远程库异常

有时候需要远程依赖包&#xff0c;但是私有包是传统的相互传递的&#xff0c;那么偏偏又去拉远程就会异常&#xff0c;所有进行操作如下

4.用python爬取保存在text中的格式为m3u8的视频

文章目录 一、爬取过程详解1.寻找视频的m3u8链接2.从网页源码中寻找视频的m3u8链接的第二部分内容3.从视频的m3u8链接获取视频 二、完整的代码 一、爬取过程详解 1.寻找视频的m3u8链接 这个文档承接了爬虫专栏的 第一节.python爬虫爬取视频网站的视频可下载的源url&#xff0…

springboot整合rabbitmq的不同工作模式详解

前提是已经安装并启动了rabbitmq&#xff0c;并且项目已经引入rabbitmq&#xff0c;完成了配置。 不同模式所需参数不同&#xff0c;生产者可以根据参数不同使用重载的convertAndSend方法。而消费者均是直接监听某个队列。 不同的交换机是实现不同工作模式的关键组件.每种交换…

智能家居4 -- 添加接收消息的初步处理

这一模块的思路和前面的语言控制模块很相似&#xff0c;差别只是调用TCP 去控制 废话少说&#xff0c;放码过来 增添/修改代码 receive_interface.c #include <pthread.h> #include <mqueue.h> #include <string.h> #include <errno.h> #include <…

李廉洋:5.8黄金原油多次小跌,今日必看独家策略。

黄金消息面分析&#xff1a;联储卡什卡利表示&#xff0c;需要更多的数据才能知道通胀回到2%目标的进展是否已经停滞&#xff0c;现在就宣布肯定已经停滞不前还为时过早。卡什卡利说&#xff1a;“我们现在的情况很好&#xff0c;劳动力市场依然强劲&#xff0c;我们可以慢慢获…