运行VINS_Fusion

2023-05-16

注释代码
(visualization、pose_grapf、pose_grapf_node)

编译:

    cd ~/catkin_ws/src
    git clone https://github.com/HKUST-Aerial-Robotics/VINS-Fusion.git
    cd ../
    catkin_make
    source ~/catkin_ws/devel/setup.bash

运行代码

   // 执行启动文件
    source ~/vins/devel/setup.bash
    roslaunch vins vins_rviz.launch
    // 开环
    source ~/vins/devel/setup.bash
    rosrun vins vins_node ~/vins/src/VINS-Fusion/config/euroc/euroc_stereo_imu_config.yaml 
    // 闭环优化
    source ~/vins/devel/setup.bash
    (optional) rosrun loop_fusion loop_fusion_node ~/vins/src/VINS-Fusion/config/euroc/euroc_stereo_imu_config.yaml 
    // 运行ROS bag
    source ~/vins/devel/setup.bash
    rosbag play /home/dyt/compare/MH_01_easy.bag

运行VINS希望输出tum型数据从而使用evo工具进行比较:

1、visualization.cpp中pubOdometry()函数

ofstream foutC(VINS_RESULT_PATH, ios::app);
        foutC.setf(ios::fixed, ios::floatfield);
        foutC.precision(0);
        foutC << header.stamp.toSec() * 1e9 << ",";
        foutC.precision(5);
        foutC << estimator.Ps[WINDOW_SIZE].x() << ","
              << estimator.Ps[WINDOW_SIZE].y() << ","
              << estimator.Ps[WINDOW_SIZE].z() << ","
              << tmp_Q.w() << ","
              << tmp_Q.x() << ","
              << tmp_Q.y() << ","
              << tmp_Q.z() << ","
              << estimator.Vs[WINDOW_SIZE].x() << ","
              << estimator.Vs[WINDOW_SIZE].y() << ","
              << estimator.Vs[WINDOW_SIZE].z() << "," << endl;
         write result to file

修改为:

ofstream foutC(VINS_RESULT_PATH, ios::app);
        foutC.setf(ios::fixed, ios::floatfield);
        foutC.precision(0);
        foutC << header.stamp.toSec() << " ";
        foutC.precision(5);
        foutC << estimator.Ps[WINDOW_SIZE].x() << " "
              << estimator.Ps[WINDOW_SIZE].y() << " "
              << estimator.Ps[WINDOW_SIZE].z() << " "
              << tmp_Q.x() << " "
              << tmp_Q.y() << " "
              << tmp_Q.z() << " "
              << tmp_Q.w() << endl;

2、pose_graph.cpp中的updatePath()函数

ofstream loop_path_file(VINS_RESULT_PATH, ios::app);
            loop_path_file.setf(ios::fixed, ios::floatfield);
            loop_path_file.precision(0);
            loop_path_file << (*it)->time_stamp * 1e9 << ",";
            loop_path_file.precision(5);
            loop_path_file  << P.x() << ","
                  << P.y() << ","
                  << P.z() << ","
                  << Q.w() << ","
                  << Q.x() << ","
                  << Q.y() << ","
                  << Q.z() << ","
                  << endl;

修改为:

ofstream loop_path_file(VINS_RESULT_PATH, ios::app);
            loop_path_file.setf(ios::fixed, ios::floatfield);
            loop_path_file.precision(0);
            loop_path_file << (*it)->time_stamp << " ";
            loop_path_file.precision(5);
            loop_path_file  << P.x() << " "
                            << P.y() << " "
                            << P.z() << " "
                            << Q.x() << " "
                            << Q.y() << " "
                            << Q.z() << " "
                            << Q.w() << endl;

3、pose_graph.cpp文件中addKeyFrame()函数

ofstream loop_path_file(VINS_RESULT_PATH, ios::app);
        loop_path_file.setf(ios::fixed, ios::floatfield);
        loop_path_file.precision(0);
        loop_path_file << cur_kf->time_stamp * 1e9 << ",";
        loop_path_file.precision(5);
        loop_path_file  << P.x() << ","
              << P.y() << ","
              << P.z() << ","
              << Q.w() << ","
              << Q.x() << ","
              << Q.y() << ","
              << Q.z() << ","
              << endl;

修改为:

ofstream loop_path_file(VINS_RESULT_PATH, ios::app);
        loop_path_file.setf(ios::fixed, ios::floatfield);
        loop_path_file.precision(0);
        loop_path_file << cur_kf->time_stamp << " ";
        loop_path_file.precision(5);
        loop_path_file  << P.x() << " "
                        << P.y() << " "
                        << P.z() << " "
                        << Q.x() << " "
                        << Q.y() << " "
                        << Q.z() << " "
                        << Q.w() << endl;

4、pose_graph_node.cpp中的main()函数
修改为txt文件:

VINS_RESULT_PATH = VINS_RESULT_PATH + "/vins_result_loop.txt";

最后编译。

遇到问题:

在运行vins输出轨迹与真值比较时,会发现对于有的数据来说无法对齐。需要查看输出函数时间精度,因为evo是根据时间对齐,当时间精度较低,甚至数个数据对应同一时间时,对齐精度较差。

代码解析:

1、KITTIGPSTest.cpp (KITTI数据集 中 双目 + GPS)
读取GPS的数据,并以 相应的 topic 发出去,为后面的 global_fusion作准备,实现 数据的融合

pubGPS = n.advertise<sensor_msgs::NavSatFix>("/gps", 1000);

2、 KITTIOdomTest.cpp(KITTI数据集 中 双目)

3、rosNodeTest.cpp (EUROC数据集 单目 + IMU)

运行车载KITTI数据:

(修改重力信息msckf_vio.cpp,配置信息)

先提取IMU信息

roscore

source devel/setup.bash
roslaunch vins vins_rviz.launch

 
source  devel/setup.bash  
rosrun vins kitti /home/dyt/VINS/src/VINS-Fusion/config/kitti_raw/kitti_10_03_config1.yaml /home/dyt/2011_10_03/2011_10_03_drive_0042_sync/

运行KITTI:

添加kitti_vio.cpp

/*
说明:
本程序尝试:相机+IMU+GPS, 其实VINS-fusion 已经具备这个条件了,主要在于结合;
本次程序是rosNodeTest.cpp 和 KITTIGPS.cpp 的结合;
通过读取不同的配置文件,可以决定是单目相机还是双目相机;
先尝试用Kitti的数据,在尝试用自己采集的数据!
*/
#include <iomanip>
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <map>
#include <thread>
#include <mutex>
#include <cmath>
#include <string>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <ros/ros.h>
#include <sensor_msgs/NavSatFix.h>
#include "estimator/estimator.h"
#include "utility/visualization.h"
#include "kitti_vio.h"
 
 
using namespace std;
using namespace Eigen;
 
Estimator estimator;
void feature_callback(const sensor_msgs::PointCloudConstPtr &feature_msg)
{
    map<int, vector<pair<int, Eigen::Matrix<double, 7, 1>>>> featureFrame;
    for (unsigned int i = 0; i < feature_msg->points.size(); i++)
    {
        int feature_id = feature_msg->channels[0].values[i];
        int camera_id = feature_msg->channels[1].values[i];
        double x = feature_msg->points[i].x;
        double y = feature_msg->points[i].y;
        double z = feature_msg->points[i].z;
        double p_u = feature_msg->channels[2].values[i];
        double p_v = feature_msg->channels[3].values[i];
        double velocity_x = feature_msg->channels[4].values[i];
        double velocity_y = feature_msg->channels[5].values[i];
        if(feature_msg->channels.size() > 5)
        {
            double gx = feature_msg->channels[6].values[i];
            double gy = feature_msg->channels[7].values[i];
            double gz = feature_msg->channels[8].values[i];
            pts_gt[feature_id] = Eigen::Vector3d(gx, gy, gz);
            //printf("receive pts gt %d %f %f %f\n", feature_id, gx, gy, gz);
        }
        ROS_ASSERT(z == 1);
        Eigen::Matrix<double, 7, 1> xyz_uv_velocity;
        xyz_uv_velocity << x, y, z, p_u, p_v, velocity_x, velocity_y;
        featureFrame[feature_id].emplace_back(camera_id,  xyz_uv_velocity);
    }
    double t = feature_msg->header.stamp.toSec();
    estimator.inputFeature(t, featureFrame);
    return;
}
 
 
void restart_callback(const std_msgs::BoolConstPtr &restart_msg)
{
    if (restart_msg->data == true)
    {
        ROS_WARN("restart the estimator!");
        estimator.clearState();
        estimator.setParameter();
    }
    return;
}
 
void imu_switch_callback(const std_msgs::BoolConstPtr &switch_msg)
{
    if (switch_msg->data == true)
    {
        ROS_WARN("use IMU!");
        estimator.changeSensorType(1, STEREO);
    }
    else
    {
        ROS_WARN("disable IMU!");
        estimator.changeSensorType(0, STEREO);
    }
    return;
}
 
void cam_switch_callback(const std_msgs::BoolConstPtr &switch_msg)
{
    if (switch_msg->data == true)
    {
        ROS_WARN("use stereo!");
        estimator.changeSensorType(USE_IMU, 1);
    }
    else
    {
        ROS_WARN("use mono camera (left)!");
        estimator.changeSensorType(USE_IMU, 0);
    }
    return;
}
 

 
void readIMUdata(const std::string &line, IMU_MSG &imuObs);


 
 
int main(int argc, char** argv)
{
  	ros::init(argc, argv, "vins_estimator");
	ros::NodeHandle n("~");
	ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME, ros::console::levels::Info);
 
    ros::Publisher pubLeftImage = n.advertise<sensor_msgs::Image>("/leftImage",1000);
	ros::Publisher pubRightImage = n.advertise<sensor_msgs::Image>("/rightImage",1000);
    ros::Subscriber sub_feature = n.subscribe("/feature_tracker/feature", 2000, feature_callback);
    ros::Subscriber sub_restart = n.subscribe("/vins_restart", 100, restart_callback);
    ros::Subscriber sub_imu_switch = n.subscribe("/vins_imu_switch", 100, imu_switch_callback);
    ros::Subscriber sub_cam_switch = n.subscribe("/vins_cam_switch", 100, cam_switch_callback);

     
	if(argc != 3)
	{
		printf("please intput: rosrun vins camera_IMU_GPS_test [config file] [data folder] \n"
			   "for example: rosrun vins camera_IMU_GPS_test "
			   "~/catkin_ws/src/VINS-Fusion/config/test_data/stereo_imu_gps_config.yaml "
			   "/home/dyt/2011_10_03_drive_0042_sync/ \n");
		return 1;
	}
    
	string config_file = argv[1];//stereo_imu_gps_config.yaml
	printf("config_file: %s\n", argv[1]);
    
	string sequence = argv[2];   //---/home/hltt3838/kitti_data/2011_10_03_drive_0042_sync/
	printf("read sequence: %s\n", argv[2]);
	string dataPath = sequence + "/";  
    
    //1、读取imu的 txt 文件,一行一行读取
    double init_imu_time;
    IMU_MSG imuObs;
    std::string line_imu;
    std::string imuPath = dataPath + "imu_data/imu.txt";
    std::ifstream  csv_IMUfile(imuPath); 
    if (!csv_IMUfile)
    {
	    printf("cannot find imu Path \n" );
	    return 0;          
	}
    std::getline(csv_IMUfile, line_imu); //header, 获得的第一个IMU数据
    
    readIMUdata(line_imu, imuObs);
    init_imu_time = imuObs.time;
    printf("init_imu_time: %10.5f \n", init_imu_time);
	
  
    
    
    //3、读取图像时间,整个文件读取,存放到 imageTimeList,两个相机对齐了,没有进行判断
    //Cam0
    double init_cam_time;
	FILE* file;
	file = std::fopen((dataPath + "image_00/timestamps.txt").c_str() , "r");
	if(file == NULL)
    {
	    printf("cannot find file: %simage_00/timestamps.txt \n", dataPath.c_str());
	    ROS_BREAK();
	    return 0;          
	}
	vector<double> image0TimeList;
	int year, month, day;
	int hour, minute;
	double second;
	while (fscanf(file, "%d-%d-%d %d:%d:%lf", &year, &month, &day, &hour, &minute, &second) != EOF)
	{
	    image0TimeList.push_back(hour * 60 * 60 + minute * 60 + second);
	}
	std::fclose(file);
    
    
    init_cam_time = image0TimeList[0]; 
    printf("init_cam_time: %10.5f \n", init_cam_time);
    
    double baseTime;
    baseTime = min(init_imu_time,init_cam_time);
    printf("baseTime: %10.5f \n", baseTime);
    
    //4、读取配置参数和发布主题
    readParameters(config_file);
	estimator.setParameter();
	registerPub(n);
    
    //5、VIO的结果输出保存文件
    FILE* outFile;
    FILE* outFile1;
	outFile = fopen((OUTPUT_FOLDER + "/vio.txt").c_str(),"w");
    outFile1 = fopen((OUTPUT_FOLDER + "/vio_kitti.txt").c_str(),"w");
	if(outFile == NULL)
    printf("Output vio path dosen't exist: %s\n", OUTPUT_FOLDER.c_str());
	string leftImagePath, rightImagePath;
	cv::Mat imLeft, imRight;
    
    
    //6、遍历整个图像
    for (size_t i = 0; i < image0TimeList.size(); i++)
	{	
        int num_imu = 0;
		if(ros::ok())
		{
			printf("process image %d\n", (int)i);
			stringstream ss;
			ss << setfill('0') << setw(10) << i;
			leftImagePath = dataPath + "image_00/data/" + ss.str() + ".png";
			rightImagePath = dataPath + "image_01/data/" + ss.str() + ".png";
            
			printf("%s\n", leftImagePath.c_str() );
			printf("%s\n", rightImagePath.c_str() );
            double imgTime = 0; 
           
            imLeft  = cv::imread(leftImagePath, CV_LOAD_IMAGE_GRAYSCALE );
            imRight = cv::imread(rightImagePath, CV_LOAD_IMAGE_GRAYSCALE );
            
            imgTime = image0TimeList[i] - baseTime;
            printf("image time: %10.5f \n", imgTime);
           
            
			
   //---------------------加上IMU-------------------------//       
            //读取imu的信息
            while (std::getline(csv_IMUfile, line_imu))
            {
               num_imu++;
               printf("process imu %d\n",num_imu);
               readIMUdata(line_imu, imuObs);
               double imuTime = imuObs.time - baseTime;
               printf("imu time: %10.5f \n", imuTime);
                
               Vector3d acc = imuObs.acc;
               Vector3d gyr = imuObs.gyr;
                   
               estimator.inputIMU(imuTime, acc, gyr);
                   
               if (imuTime >= imgTime) //简单的时间同步,IMU的时间戳是不大于图像的
                {
                    break;
                }
            }
     //---------------------加上IMU-------------------------//     
     
            if(STEREO)//双目为1,否则为0
            {
              estimator.inputImage(imgTime,imLeft, imRight);
            }
            else
              estimator.inputImage(imgTime, imLeft);
 
        
			Eigen::Matrix<double, 4, 4> pose;
            Eigen::Vector3d P;
            Eigen::Quaterniond Q;
            double T;
			estimator.getPoseInWorldFrame(pose);
            estimator.getPoseInWorldFrame1(T,P,Q);
			if(outFile1 != NULL){
				fprintf (outFile1, "%f %f %f %f %f %f %f %f %f %f %f %f\n",pose(0,0), pose(0,1), pose(0,2),pose(0,3),
																	       pose(1,0), pose(1,1), pose(1,2),pose(1,3),
																	       pose(2,0), pose(2,1), pose(2,2),pose(2,3));
			
			 //cv::imshow("leftImage", imLeft);
			 //cv::imshow("rightImage", imRight);
			 //cv::waitKey(2);
                
                 // write result to file
        ofstream foutC("/home/dyt/VINS/src/VINS-Fusion/output_kitti/kitti_text.txt", ios::app);
        foutC.setf(ios::fixed, ios::floatfield);
        foutC.precision(15);
        //foutC << header.stamp.toSec() * 1e9 << ",";
        foutC << T  << " ";
        foutC.precision(5);
        foutC << P.x() << " "
              << P.y() << " "
              << P.z() << " "
              << Q.x() << " "
              << Q.y() << " "
              << Q.z() << " "
              << Q.w() << endl;
        foutC.close();
        
        fprintf(outFile, "%f %f %f %f %f %f %f %f\n", T, P.x(), P.y(), P.z(),
                                                          Q.x(), Q.y(), Q.z(), Q.w());
            }
		}
		else
			break;
	}
	
	if(outFile != NULL)
		fclose (outFile);
    
    
    return 0;
}   
 
void readIMUdata(const std::string &line, IMU_MSG &imuObs)
{
    std::stringstream  lineStream(line);
    std::string        dataRecord[7];
    std::getline(lineStream, dataRecord[0], ' ');//这里的数据间是空格, 如果有逗号,用','
    std::getline(lineStream, dataRecord[1], ' ');
    std::getline(lineStream, dataRecord[2], ' ');
    std::getline(lineStream, dataRecord[3], ' ');
    std::getline(lineStream, dataRecord[4], ' ');
    std::getline(lineStream, dataRecord[5], ' ');
    std::getline(lineStream, dataRecord[6], ' ');
    
    imuObs.time = std::stod(dataRecord[0]); //时间:s;
             
    imuObs.acc[0] = std::stod(dataRecord[1]);
    imuObs.acc[1] = std::stod(dataRecord[2]);
    imuObs.acc[2] = std::stod(dataRecord[3]);
 
    imuObs.gyr[0] = std::stod(dataRecord[4]);
    imuObs.gyr[1] = std::stod(dataRecord[5]);
    imuObs.gyr[2] = std::stod(dataRecord[6]);
}
 

添加kitti_vio.h


#pragma once
#include<chrono>
#include <Eigen/Dense>
#include <opencv2/opencv.hpp>
 
 
struct IMU_MSG
{
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
    double time;
    Eigen::Vector3d acc;
    Eigen::Vector3d gyr;
    IMU_MSG &operator =(const IMU_MSG &other)
    {
        time = other.time;
        acc = other.acc;
        gyr = other.gyr;
        return *this;
    }
};
 

 
double min(double x,double y,double z )
{
    return x < y ? (x < z ? x : z) : (y < z ? y : z);
}



KITTI

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

运行VINS_Fusion 的相关文章

  • VINS - Fusion GPS/VIO 融合 二、数据融合

    https zhuanlan zhihu com p 75492883 一 简介 源代码 xff1a VINS Fusion 数据集 xff1a KITTI 数据 程序入口 xff1a globalOptNode cpp 二 程序解读 2
  • 树莓派4B(ubuntu mate系统)使用d435i运行vins

    树莓派4B xff08 ubuntu mate系统 xff09 使用d435i运行vins 提示本文为随手笔记 xff0c 并不严谨 xff0c 可参考 xff1a 博客和博客进行配置 树莓派 ubuntu mate 20系统安装ros的步
  • 【SLAM】VINS-Fusion解析——流程

    VINS Fusion分析 因为时间原因 xff0c 没有像vins mono看的和写的那么具体 有时间的话我会补充完整版 vins fusion不像mono那样有三个node xff0c 它只有一个node xff0c 在rosNodeT
  • 2 用D435i运行VINS-fusion

    文章目录 1 VINS fusion的安装1 1 环境和依赖的安装1 2 编译VINS Fusion1 3 编译错误解决方法 2 VINS Fusion跑数据集3 用相机运行VINS Fusion 环境 xff1a Ubuntu20 04
  • 【学习SLAM】vins笔记

    VINS ROS source catkin ws devel setup bash 3 1 1 Open three terminals launch the vins estimator rviz and play the bag fi
  • VINS技术路线与代码详解

    VINS技术路线 写在前面 xff1a 本文整和自己的思路 xff0c 希望对学习VINS或者VIO的同学有所帮助 xff0c 如果你觉得文章写的对你的理解有一点帮助 xff0c 可以推荐给周围的小伙伴们 xff0c 当然 xff0c 如果
  • VINS-Mono代码学习记录(四)---estimator_node

    写在前面的话 终于把feature tracker这一个node给整理好了 xff0c 那些都是之前就已经看过的内容 xff0c 所以整理起来比较快 xff0c 接下来就慢慢边学边整理吧 xff0c 这次先来看estimator node
  • vins 解读_代码解读 | VINS_Mono中的鱼眼相机模型

    本文作者是计算机视觉life公众号成员蔡量力 xff0c 由于格式问题部分内容显示可能有问题 xff0c 更好的阅读体验 xff0c 请查看原文链接 xff1a 代码解读 VINS Mono中的鱼眼相机模型 VINS Mono中的鱼眼相机模
  • VINS-Mono跑Kitti数据集

    参考文章 xff1a VINS Mono KITT00 测试 知乎 如何在kitti raw data上跑起vins mono 知乎 实际上我参考的是LIO SAM里将KITTI转化为bag的方法 Debug https blog csdn
  • vins位姿图优化

    我们 的滑动窗口和边缘化方案限制了计算的复杂性 xff0c 但也给系统带来了累积漂移 更确切地说 xff0c 漂移发生在全局三维位置 x y z 和围绕重力方向的旋转 yaw 为了消除漂移 xff0c 提出了一种与单目VIO无缝集成的紧耦合
  • 在ubuntu20.04上配置VINS_Fusion(亲测有效,一应俱全)

    最近在做科研训练的时候配置了HKUST Aerial Robotics实验室的VINS Fusion代码项目 xff0c 经历了一些编译报错的问题 xff0c 在网上查找的时候博客内容良莠不齐 xff0c 且实质针对性意见不多 xff0c
  • VINS-FUSION-GPU在jetson nx上的实现

    需要安装经过修改的Ubuntu18系统 https span class token operator span span class token comment developer nvidia com zh cn embedded do
  • VINS-Mono论文笔记(中)

    VINS Mono论文笔记 中 前言1 初始化过程1 1 视觉重构1 2 视觉惯性联合 2 紧耦合的单目VIO系统2 1 公式2 2 imu残差2 3 视觉残差2 4 边缘化残差2 5 针对相机实时帧率的纯运动视觉惯性状态估计器2 6 im
  • VINS记录

    euroc launch lt launch gt lt arg name 61 34 config path 34 default 61 34 find feature tracker config euroc euroc config
  • VINS-Mono视觉初始化代码详解

    摘要 视觉初始化的过程是至关重要的 xff0c 如果在刚开始不能给出很好的位姿态估计 xff0c 那么也就不能对IMU的参数进行精确的标定 这里就体现了多传感器融合的思想 xff0c 当一个传感器的数据具有不确定性的时候 xff0c 我们需
  • VINS-Mono代码阅读笔记(十三):posegraph中四自由度位姿优化

    本篇笔记紧接着VINS Mono代码阅读笔记 xff08 十二 xff09 xff1a 将关键帧加入位姿图当中 xff0c 来学习pose graph当中的紧耦合优化部分 在重定位完成之后 xff0c 进行位姿图优化是为了将已经产生的所有位
  • D435i运行VINS-mono以及Kalib标定

    D435i运行VINS mono以及Kalib标定 系统说明 xff1a Ubuntu 18 04 内核版本 xff1a 5 4 0 1 运行VINS mono 参考博客VINS xff08 D435i xff09 测试 问题 xff1a
  • 2021-08-06

    在编译OKVIS中 执行make j8时报错的解决方法 1 根据github上OKVIS的安装步骤一步一步执行 由于github经常进不去 我就进了gitee网站查到OKVIS的安装步骤 参考链接 https gitee com bill4
  • 从 .Net v4.0 程序集链接到 .Net v2.0 程序集似乎也链接(和别名)mscorlib v2.0。为什么?

    我有一个 Net 程序集 它导入与 v2 0 运行时链接的程序集 我遇到的问题是 当我尝试在程序集上运行一些测试时 Fusion 尝试加载依赖程序集的错误版本 查看程序集清单后 我明白了原因 错误的版本FSharp Core已连接 在我的构
  • TypeLoadException 说“没有实现”,但它已实现

    我的测试机器上有一个非常奇怪的错误 错误是 System TypeLoadException Method SetShort in type DummyItem from assembly ActiveViewers does not ha

随机推荐

  • Failed to set attribute: Invalid input data or parameter 解决

    arm64 swconfig 配置vlan 失败问题 Failed to set attribute Invalid input data or parameter 解决 内核版本 xff1a linux 5 20 26 现象 xff1a
  • 使用PIXIWell_RF 射频模块 虚拟GPS windows系统

    使用PIXIWell RF 射频模块 虚拟GPS windows系统 文章目录 使用PIXIWell RF 射频模块 虚拟GPS windows系统 前言一 PIXIWell RF射频是什么 xff1f 二 虚拟GPS使用步骤1 硬件连接2
  • DJI Mavic 2 & AUTEL Evo无人机无线链路_射频_RF测试

    背景 xff1a 出于对DJI大疆无人机的好奇 xff0c 航时上的持久 xff0c 尺寸上的拔尖 xff0c 距离上的长远 xff1b 让我们来看看它的它的无线链路 射频 RF波形长什么样子的 AUTEL Evo无人机可能很多人不太了解
  • 我如何使用iPad作为学习工具

    引言 如果不懂得使用app xff0c 其实iPad就是一块屏幕而已 如果你已经有iPad xff0c 那么 xff0c 恭喜你 xff0c 这篇文章正是为了让它发挥出更大价值 如果你还没有 xff0c 那么你就又多了一个剁手的理由 上我的
  • 利用STM32实现自平衡机器人功能与方法

    将机器人整体开源 xff0c 同时总结一下机器人搭建过程中遇到的坑和未来的改进方向 在分享的文件里包含了结构设计 程序控制 电路设计以及其他模块相关资料供大家参考 第一 xff1a 机器人原理分析 首先来看成品图 xff1a 如图所示 xf
  • Ubuntu 终端(terminal) 配置文件修改后保存方法

    1 ESC退出INSERT模式进入命令模式 2 输入 w 保存 输入 wq 保存退出 输入 wq 保存并强制退出
  • Linux复习: semaphore.h信号量和生产者消费者

    点击查看demo代码 demo运行结果如图 借用网上的一段话 在线程世界里 xff0c 生产者就是生产数据的线程 xff0c 消费者就是消费数据的线程 在多线程开发当中 xff0c 如果生产者处理速度很快 xff0c 而消费者处理速度很慢
  • ubuntu使用经验

    1 查看文件夹大小 xff1a du h max depth 61 1 max depth 61 1表示查看当前目录下所有文件夹各自的大小 2 查看ubuntu版本信息 xff1a cat proc version Linux versio
  • 如何得到github上传的以前的版本

    有时候我们可能想得到github上老版本的代码 这个时候先 git clone xxxx 现在最新版本的代码 然后cd xx 到文件夹里面 然后 git log commit b56065418b63a971fcf4f8f35d058513
  • STM32---串口实现在应用程序的固件更新(IAP)

    背景 xff1a 在产品发布后 xff0c 可能需要对固件进行更新或者升级 xff0c 那么在影响产品正常运行的情况下 xff0c 如果升级固件呢 xff1f 理论 xff1a 下面的所有理论部分内容参考 STM32开发指南 什么是IAP
  • 利用protobuf和zmq实现网络通信

    经过不短时间的调试 xff0c 终于搞定了protobuf和zmq两个第三方库的编译和使用 xff0c 并且参考往事前辈的代码编写了两者之间的通信demo protobuf的编译和使用 xff0c 前面有篇博客已经讲了 zmq的编译我用的是
  • react-create-app src引入目录外部文件冲突问题:Relative imports outside of src/ are not supported....

    使用react create app构建的项目 xff0c 当src文件夹下文件想引用src文件夹外文件因为官方限制问题会报以下错误 Module not found You attempted to import which falls
  • OpenStack Neutron ML2

    Neutron 系列文章 Neutron Topic Tree xff1a 本文所有的内容都基于OpenStack Pike版本 其实在2016年 xff0c 我曾经在IBM Developerworks上写过一篇文章介绍Neutron M
  • kettle 通过java脚本对数据进行标注

    在项目当中遇到一种情况 xff1a 我需要根据不同字段的值综合判断该数据属于我划分的哪种类型 如果是单个字段我们可以根据kettle提供的switch case 组件进行判断并赋值 xff0c 但是如果通过多个字段或者是添加某种限定条件对数
  • 经典C++笔试题目100例,接近实际,值得一看!

    第一部分 xff1a C 43 43 与C语言的差异 xff08 1 18 xff09 1 C 和 C 43 43 中 struct 有什么区别 xff1f Protection行为能否定义函数C无否 xff0c 但可以有函数指针C 43
  • 运行msckf_vio

    1 编译 cd span class token operator span span class token operator span msckf catkin make span class token operator span p
  • Ubuntu下vscode使用

    目录 1 安装2 插件 xff08 通过左边栏的Extension栏目安装 xff0c 或者Ctrl 43 Shift 43 X xff09 3 配置launch json文件 xff08 Ctrl 43 Shift 43 D xff09
  • 跑msckf程序闪退问题

    在前端追踪中得到的距离 xff0c 需要加一个不小于35的阈值
  • MSCKF理论学习

    最近在学习MSCKF代码 xff0c 在这里记录一下 参考博客 xff1a MSCKF那些事儿 一步步深入了解S MSCKF 一步一步推导S MSCKF系列 1 MSCKF原理 MSCKF的目标是解决EKF SLAM的维数爆炸问题 传统EK
  • 运行VINS_Fusion

    注释代码 visualization pose grapf pose grapf node 编译 xff1a cd span class token operator span span class token operator span