星网宇达(惯导+IMU)设备实现自动采点

2023-05-16

一、创建和打开gps_Road.txt文件,准备往里写数据

FILE *p = NULL;
p = fopen("gps_Road.txt", "w");//定义一个指针也就是地址p存放gps_Road.txt里的数据,fopen():先查看gps_Road.txt这个文件有没有,没有就创建一个gps_Road.txt文件,然后打开准备往里写

二、创建GPFPD数据接收线程

pthread_t RecvFromIMU_tid;//pthread_t类型的参数
pthread_create(&RecvFromIMU_tid, NULL, RecvFromIMU_pthread, NULL);//四个参数分别是pthread_t类型的参数、线程属性、线程函数、线程函数的参数
pthread_join(RecvFromIMU_tid, NULL);

int initialize()
{
    struct termios oldtio,newtio; 
    g_fd=open(UART_NAME, O_RDWR|O_NOCTTY);  
    if(g_fd<0)  {  
        printf("MC: open port fail!\n");        
        return -1;
    } 
    set_speed(g_fd,115200);

    if (set_parity(g_fd,8,1,'N') == false)  {
		printf("Set Parity Error\n");
		return -1;
	}
    return 0; 
    fcntl(g_fd,F_SETFL,0);
    /*将目前终端机的结构保存至oldtio结构*/  
    tcgetattr(g_fd,&oldtio);  
    /*清除newtio结构,重新设置通信协议*/  
    bzero(&newtio,sizeof(newtio));  
    /*通信协议设为8N1,8位数据位,N没有效验,1位结束位*/  
    newtio.c_cflag = BAUDRATE | CS8 | CLOCAL| CREAD;  
    newtio.c_iflag = IGNPAR;  
    newtio.c_oflag = 0;  
    /*设置为正规模式*/  
    //newtio.c_lflag=ICANON;
    newtio.c_lflag=0;
    newtio.c_cc[VTIME]=0;
    newtio.c_cc[VMIN]=69; 
    /*清除所有队列在串口的输入*/  
    tcflush(g_fd,TCIFLUSH);  
     /*新的termios的结构作为通信端口的参数*/  
    tcsetattr(g_fd,TCSANOW,&newtio); 
}

void *RecvFromIMU_pthread(void *args)
{
    memset(g_RecvDataFromRTK,0,sizeof(g_RecvDataFromRTK));//初始化g_RecvDataFromRTK[]这个数组
    if(IsInit==false)//bool类型,反正都会是1
    {
        if(initialize()<0)//星网宇达初始化步骤
        {
            printf("MC: 打开串口配置参数失败\n");
            return 0;
        }
        IsInit=true;
        printf("MC: 打开串口配置参数成功\n");
    }
    //return 0;
	memset(&g_RecvDataFromRTK_0, 0, sizeof(g_RecvDataFromRTK_0));
	memset(&g_RecvDataFromRTK_1, 0, sizeof(g_RecvDataFromRTK_1));
	int nBytes_0 = 0;
	int nBytes_1 = 0;
    while(1)
    {
        usleep(10000*50);
		memset(&g_RecvDataFromRTK_0, 0, sizeof(g_RecvDataFromRTK_0));
        memset(&g_RecvDataFromRTK_1, 0, sizeof(g_RecvDataFromRTK_1));
		//memcpy(g_RecvDataFromRTK_0, g_RecvDataFromRTK_1, sizeof(g_RecvDataFromRTK_1));
		nBytes_0 = nBytes_1;
		nBytes_1 = read(g_fd, g_RecvDataFromRTK_1, 200);//读串口里面的数据:把g_fd标志位指向的地址里的前200位数据读到g_RecvDataFromRTK_1[]中
		//printf("%s\n",g_RecvDataFromRTK_0);
        //printf("g_RecvDataFromRTK_1:%s\n",g_RecvDataFromRTK_1);
        //printf("%d\n",strlen(g_RecvDataFromRTK_1));
        usleep(10000);
		//printf("nBytes0=%d,nBytes=%d\n", nBytes_0, nBytes_1);
		if (g_RecvDataFromRTK_1[0] == '$')//判断数组首地址的数据是否是'$'
		{
			char *ret;
            int i;
            for(i = 0;i < 200;i++)
            {
                if(g_RecvDataFromRTK_1[i]=='*')//遍历整个数组,遍历到GPFPD的尾部就是'*'的地方就停止遍历,跳出整个循环
                {
                    break;
                }                  
            }
            if(i > 70&&i!=200)
            {
                process_len = i;//整个GPFPD数据的长度是120字节,如果在以上区间就说明正确
                //printf("g_RecvDataFromRTK_1:%s\n",g_RecvDataFromRTK_1);
                for(int j=0;j<i;j++)
                {
                    g_DataCombine[j] = g_RecvDataFromRTK_1[j];
                }
                pthread_mutex_lock(&gMutex_SC_data);
				memcpy(g_ProcDataFromSCBuf, g_DataCombine, DATALEN);//把整个GPFPD数据存放到g_ProcDataFromSCBuf[]数组中
				pthread_cond_signal(&gCond_SC_data);
				pthread_mutex_unlock(&gMutex_SC_data);
            }							
		}
    }
    return 0;
}

三、数据处理线程

pthread_t AnalysisIMU_tid;
pthread_create(&AnalysisIMU_tid, NULL, AnalysisIMU_pthread, NULL);
pthread_join(AnalysisIMU_tid, NULL);

void *AnalysisIMU_pthread(void *args)
{
    unsigned char localproc_SCData[200];
    int localproc_len=0;
    int num=0;
	//memset(&g_IMUdata, 0, sizeof(IMUdata));
    while(1)
    {
        
            pthread_mutex_lock(&gMutex_SC_data); 
            pthread_cond_wait(&gCond_SC_data,&gMutex_SC_data);
            memcpy(localproc_SCData,g_ProcDataFromSCBuf,process_len) ;
            localproc_len=process_len;
            num=0;
            //printf("接收到%d个字节\n",localproc_len);
            pthread_mutex_unlock(&gMutex_SC_data);

            double g_Lattitude_tmp =0;
            double g_Longitude_tmp =0;
            double g_Heading_tmp=0;
            for(int i=0;i<localproc_len;i++)
            {
                if(localproc_SCData[i]==0x2c)//0x2c是','表明的是GPFPD隔开的逗号点
                {
                    num++;//num++就是先使用num原本的数字然后再加一
                    if(num==3)//原本是第四位,因为num++的原因变成第三位
                    {
                        for(int j=i+1;;j++)
                        {
                            if(localproc_SCData[j]==0x2c)//遇到','就会跳出整个循环,表明转向角数据已经找到,在两个','之间
                            {
                                break;
                            }
                            if(localproc_SCData[j]!=0x2e)//遇到'.'就要排除它,比如说345.255就要把'.'去除
                            {
                                g_Heading_tmp*=10;
                                g_Heading_tmp+=(localproc_SCData[j]-48);//把每一位取出来的数字从字符串转换成数字,需要每一位减48
                            }
                       
                        }
                        g_Heading_tmp/=1000;//保留三位小数
                        //printf("g_Heading----------%f\n",g_Heading);
                    }
                    if(num==6)
                    {
                        for(int j=i+1;;j++)
                        {
                            if(localproc_SCData[j]==0x2c)
                            {
                                break;
                            }
                            if(localproc_SCData[j]!=0x2e)
                            {
                                g_Lattitude_tmp*=10;
                                g_Lattitude_tmp+=(localproc_SCData[j]-48);
                            }
                        }
                        g_Lattitude_tmp/=10000000;
                        //printf("g_Lattitude----------%f\n",g_Lattitude);
                    }
                    if(num==7)
                    {
                        for(int j=i+1;;j++)
                        {
                            if(localproc_SCData[j]==0x2c)
                            {
                                break;
                            }
                            if(localproc_SCData[j]!=0x2e)
                            {
                                g_Longitude_tmp*=10;
                                g_Longitude_tmp+=(localproc_SCData[j]-48);
                            }
                        }
                        g_Longitude_tmp/=10000000;
                        //printf("g_Longitude----------%f\n",g_Longitude);
                    }
                }
            }
            g_Lattitude = g_Lattitude_tmp;
            g_Longitude = g_Longitude_tmp;
            g_Heading = g_Heading_tmp;
            if(file_point_num == 0)
            {
                last_g_Lattitude = g_Lattitude;
                last_g_Longitude = g_Longitude;
                last_g_Heading = g_Heading;
                file_point_num++;
            }
            else
            {
                double distance = ntzx_GPS_length(last_g_Longitude,last_g_Lattitude,
                g_Longitude,g_Lattitude);
                if(distance >= 0.8)
                {
                    fprintf(p,"$GPFPD,1451,368123.30,%lf,0.128,1.579,%lf,%lf,394.98,-0.157,0.019,-0.345,3.898,7,8,1*7B\n",
                    g_Heading,g_Lattitude,g_Longitude);
                    fflush(p);
                    last_g_Lattitude = g_Lattitude;
                    last_g_Longitude = g_Longitude;
                    last_g_Heading = g_Heading;
                    file_point_num++;
                    printf("hit!\n");
                }
            }
    }
    return 0;
}

四、Makefile

#指定项目.c所存在的文件夹
SRC_DIR=					./
vpath %.c					./:./MC:./CAN
                            

#输出文件名
OUTPUT:=					route_get

#输出目录
OUTPUT_DIR=					../RELEASE

#交叉编译1
#CC:=						arm-linux-gcc
#CXX:=						arm-linux-g++
#LIB_DIR:=					-L$(PROJ_DIR)/lib/arm-linux-gcc

#交叉编译2
#CC:=						arm-linux-gnueabihf-gcc
#CXX:=						arm-linux-gnueabihf-g++
#LIB_DIR:=					-L$(PROJ_DIR)/lib/arm-linux-gnueabihf-gcc
 
#交叉编译3
#CC:=						aarch64-himix100-linux-gcc
#CXX:=						aarch64-himix100-linux-g++
#LIB_DIR:=					-L../../LIB/aarch64-himix100-linux-gcc


#标准编译
CC:=						gcc -g
CXX:=						g++
LIB_DIR:=					-L../LIB/gcc

#包含路径
INCLUDE_DIR+=				-I./MC
INCLUDE_DIR+=				-I./CAN

#依赖项
LIB:=						-lrt -lpthread -lm#-ludev #-nostdinc

#遍历所有子目录中的.c文件
SRC =						$(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c))

#指定.o文件的存放目录
OBJ_DIR=					../OBJ

#目标文件
OBJ:=						$(patsubst %.c,%.o,$(SRC))
#$(info "OBJ:$(OBJ)")#调试打印

#去.o文件地址,只保留文件名
OBJ_WITHOUT_DIR = $(notdir $(OBJ))
#$(info "OBJ_WITHOUT_DIR:$(OBJ_WITHOUT_DIR)")#调试打印

#将生成的.o文件与指定目录相绑定
OBJ_WITH_DIR = $(addprefix $(OBJ_DIR)/,$(OBJ_WITHOUT_DIR))
#$(info "OBJ_WITH_DIR:$(OBJ_WITH_DIR)")#调试打印

#必须先执行 OBJ_WITHOUT_DIR ,才能有OBJ_WITH_DIR依赖
all: clean $(OBJ_WITHOUT_DIR) $(OUTPUT)

$(OUTPUT):$(OBJ_WITH_DIR)
	$(CC) -o $(OUTPUT_DIR)/$@ $^ $(LIB_DIR) $(LIB)
%.o:%.c
	$(CC) $(INCLUDE_DIR) $(LIB_DIR) $(LIB) -c $< -o $(OBJ_DIR)/$@

clean:
	rm -rf $(OUTPUT) $(OBJ_DIR)/*.o

.PHONY: all clean

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

星网宇达(惯导+IMU)设备实现自动采点 的相关文章

  • 三位数的IMU长什么样?二位数的呢?不要钱的呢?| 为FishBot配置IMU惯性测量单元

    大家好 xff0c 我是小鱼 xff0c 上节课通过配置两轮差速控制器我们已经成功的让fishbot在gazebo中动了起来 xff0c 本节课我们通过给fishbot的URDF配置IMU传感器插件 xff0c 让IMU模块工作起来 1 惯
  • IMU与GPS传感器ESKF融合定位

    IMU与GPS传感器ESKF融合定位 文章目录 IMU与GPS传感器ESKF融合定位1 代码整体框架说明2 主要函数介绍2 1 LocalizationWrapper构造函数2 2 滤波算法进行预测2 3 通过GPS位置测量数据更新系统的状
  • IMU预积分学习

    IMU预积分学习 一 IMU状态传递方程 一 IMU状态传递方程 几种不同的表达形式 xff1a 1 lio mapping xff1a 参考大佬 xff1a lio mapping 及 VINS Mono代码及理论推导 xff08 2 x
  • STM32—驱动GY85-IMU模块

    GY85是一个惯性测量模块 xff0c 内部集成了三轴加速度计 三轴陀螺仪 电子罗盘 气压传感器等芯片 xff0c 用于测量和报告设备速度 方向 重力 xff0c 模块可以将加速度计 陀螺仪 电子罗盘等传感器的数据进行综合 xff0c 在上
  • 对IMU数据进行卡尔曼滤波

    我们要使用IMU数据 xff0c 必须对数据进行预处理 xff0c 卡尔曼滤波就是很好的方式 1 卡尔曼滤波 卡尔曼滤波 xff08 Kalman filtering xff09 是一种利用线性系统状态方程 xff0c 通过系统输入输出观测
  • Camera-IMU标定工具Kalibr的编译

    关于catkin make过程中下载suitesparse过久甚至失败的问题 xff1a 在安装kalibr时的suitesprse库时 xff0c 对应的cmakelists中会通过wget 下载压缩包 xff0c 若无法下载则整个kal
  • Kalibr 之 Camera-IMU 标定 (总结)

    Overview 欢迎访问 持续更新 xff1a https cgabc xyz posts db22c2e6 ethz asl kalibr is a toolbox that solves the following calibrati
  • ROS2中IMU话题的发布及可视化

    环境 xff1a Ubuntu 20 04 xff0c ROS2 Foxy 传感器 xff1a 维特智能BWT901CL 代码是从维特智能的示例代码修改的 xff0c 实现基本的加速度 角速度和角度读取 xff0c 发布IMU消息 这个传感
  • 多IMU车载GNSS/INS数据集及介绍

    文章目录 前言非常棒的GINS数据集采集轨迹采集时间MEMS IMU详细信息IMU测量值方程及相关误差建模参考噪声参数 安装参数文件格式描述 前言 本文作者感谢武汉大学多源智能导航实验室和牛小骥教授提供了本文所需的GNSS INS数据集 本
  • 使用IMU进行状态估计及进阶

    文章目录 前言基本思想一 姿态估计1 1 通过6轴IMU来进行姿态估计的入门级方法1 1 1 通过加速度计计算姿态1 1 2 引入陀螺仪来得到更好的姿态估计 1 2 四元数解算姿态角解析 二 姿态估算与滤波的关系2 1 状态方程和观测方程2
  • 无人车传感器 IMU与GPS数据融合进行定位机制

    前言 上一次的分享里 xff0c 我介绍了GPS的原理 xff08 三角定位 xff09 及特性 xff08 精度 频率 xff09 xff0c 同时也从无人车控制的角度 xff0c 讨论了为什么仅有GPS无法满足无人车的定位要求 为了能让
  • RealSenseD345I —— imu + camera标定

    目录 1 标定目的 2 标定准备 3 标定步骤 nbsp nbsp nbsp nbsp 1 IMU标定 nbsp nbsp nbsp
  • IMU让无人机控制变得更轻松

    多翼无人机广泛应用于监视和侦察 航空摄影和测量 搜索和救援任务 通信中继和环境监测 目前无人机的手动控制大部分基于视觉反馈 xff0c 所以操作环境中的障碍物会造成干扰 因此 xff0c 需要其他感官反馈 xff0c 例如触觉 xff0c
  • 星网宇达(惯导+IMU)设备实现自动采点

    一 创建和打开gps Road txt文件 xff0c 准备往里写数据 FILE span class token operator span p span class token operator 61 span span class t
  • realsense d435i标定imu与camera

    realsense d435i标定imu与camera 1 标定目的 realsense d435i包含两个红外相机 红外发射器 RGB相机和IMU四个模块 xff0c 显然四个传感器的空间位置是不同的 xff0c 我们在处理图像和IMU数
  • Ardupilot IMU恒温控制代码学习

    目录 文章目录 目录 摘要 第一章原理图学习 第二章恒温代码学习 1 目标温度怎么设置 摘要 本节主要学习ardupilot的IMU恒温控制代码 采用的飞控是pixhawk v5 欢迎一起交流学习 第一章原理图学习
  • Kalibr进行相机-IMU联合标定踩坑记录RuntimeError: Optimization failed!

    1 具体标定步骤 xff0c 跟网上别的一模一样 xff0c 此处就不列举 2 记录踩坑过程 xff1a RuntimeError Optimization failed 当执行到开始联合标定时 xff0c 也就是如下指令 xff1a ka
  • IMU-Allan方差分析

    使用Allan方差来确定MEMS陀螺仪的噪声参数 陀螺仪测量模型为 使用长时间静止的陀螺仪数据对陀螺仪噪声参数进行分析 上式中 三个噪声参数N 角度随机游走 K 速率随机游走 和B 偏差不稳定性 背景 Allan方差最初由David W A
  • 四元素与旋转矩阵

    如何描述三维空间中刚体的旋转 是个有趣的问题 具体地说 就是刚体上的任意一个点P x y z 围绕过原点的轴 i j k 旋转 求旋转后的点P x y z 旋转矩阵 旋转矩阵乘以点P的齐次坐标 得到旋转后的点P 因此旋转矩阵可以描述旋转 x
  • 足部IMU在复杂场景中行走定位

    随着微机电系统 MEMS 技术的快速发展 基于MEMS的惯性导航系统 INS 在任意环境的基站定位方面发挥着至关重要的作用 惯性导航具有自主性强 定位频率高 功耗低 实时性强等特点 因此更适合单兵作战 反恐行动 应急救援 消防救援等环境未知

随机推荐

  • 51单片机上数码管的静态显示和动态显示

    一 TX1C数码管介绍 共阴极和共阳极数码管 xff0c 实验板上是共阴极数码管 xff0c 6位一体的数码管 连接原理图如下面两图 xff1a 连在一起的段线 xff08 段选线即abcdefgh xff09 控制数码管亮什么数字 xff
  • 51单片机的键盘检测原理

    一 独立键盘检测 1 按键的检测原理 单片机的I O口既可以作为输出也可以作为输入使用 xff0c 检测按键时用的是输入功能 把按键的一端接地 xff0c 另一端与单片机的某个I O口相连 xff0c 开始时先给该I O口赋一个高电平 xf
  • 51单片机上AD和DA操作

    一 ADC0804的操作 1 试验板上ADC0804的接线图 AD芯片上的第5管脚INTR没有接线 xff0c 因为该实验板读取A D数据没有用中断法 xff0c 所以可以不接该引脚 2 芯片的操作时序图如下 操作芯片时基本按照此顺序操作各
  • ESP32上对flash的读取操作

    通过按键控制一个LED灯的亮和灭 xff0c 每次重启时读上一次的状态 span class token macro property span class token directive hash span span class toke
  • 正点原子stm32F407学习笔记6——外部中断实验

    一 GPIO与中断线的映射关系 GPIO 的管脚GPIOx 0 GPIOx 15 x 61 A B C D E xff0c F G H I 分别对应中断线 0 15 这样每个中断线对应了最多 9 个 IO 口 xff0c 以线 0 为例 x
  • 通俗易懂的socket select模型讲解

    通俗易懂的socket select模型讲解 FFFF ireCore 前面一篇介绍了服务器端使用多线程的方式来处理多个客户端的请求的 xff0c 但是当客户端数量增多时线程数量会急剧增加 xff0c 导致消耗大量的资源 于是就引出了服务器
  • 【esp32学习之路7——硬件定时器】

    一 概述 ESP32 的定时器分为 2 组 xff0c 每组 2 个 ESP32 内置 4 个 64 bit 通用定时器 每个定时器包含一个 16 bit 预分频器和一个64 bit 可自动重新加载向上 xff0f 向下计数器 详情可参考乐
  • gcc编译器与Makefile入门

    在Windows下开发通常使用各种IDE xff0c 但在Linux下进行C编程编译代码的话需要用到GCC编译器 一 编译流程 GCC 编译器的编译流程是 xff1a 预处理 编译 汇编和链接 预处理就是展开所有的头文件 替换程序中的宏 解
  • Linux中HTTP的请求

    HTTP请求的步骤 xff1a 1 建立TCP 通信连接 2 制定HTTP协议例如 xff1a GET HTTP 1 1 r nHost www baidu com r n r n 3 发送制定好的HTTP协议 4 接收服务器所返回的数据
  • Ubuntu安装RealSense驱动SDK

    Ubuntu安装RealSense驱动SDK 参考链接 官方链接 1 添加key span class token function sudo span apt key adv span class token parameter vari
  • (2)LOAM的安装运行——安装及运行问题解决

    真是一言难尽 xff0c 安装一步一个坎 xff0c 算吧差不多花了一天时间 xff0c 还好最后成功啦 xff01 上一篇对PCL的安装及测试进行了介绍 xff0c 下面开始安装LOAM和利用bag运行 参照https blog csdn
  • http是什么_作用以及报文详情_http的常见状态码

    http是什么 xff1f 一 http的定义 xff1a http Hypertext transfer protocol 超文本传输协议 xff0c 通过浏览器和服务器进行数据交互 xff0c 进行超文本 xff08 文本 图片 视频等
  • C++ string与int类型的转换

    Int转String 1 int 43 39 0 39 为对应的ASCLL码 可以通过强制类型转换将ASCLL码转成对应的字符 int digit 61 1 cout lt lt digit 43 39 0 39 lt lt endl 49
  • 设计性大作业(1) 简单路由器程序的设计

    简单路由器程序设计实验的具体要求为 xff1a 可在虚拟机上实现 xff0c 源码和操作文档加企鹅2805531180 xff08 1 xff09 设计和实现一个路由器程序 xff0c 要求完成的路由器程序能和现有的路由器产品 xff08
  • 堆和栈的存放内容

    栈 栈存放的是基本数据类型 43 引用变量名 int a 61 1 这里的a和1都存放在栈中 String b 61 abc 这里只有b存放在栈中 xff0c 而 34 abc 34 则存放在堆中 堆 堆存放的是new出来的对象 上述的St
  • 大字节序和小字节序

    一 基本概念 大字节序和小字节序是数据存储规则 小字节序是高位数据存储在内存高位地址 xff0c 低位数据存储在低位地址 大字节序是高位数据存储在内存低位地址 xff0c 低位数据存储在高位地址 二 程序判断 include lt iost
  • IMU让无人机控制变得更轻松

    多翼无人机广泛应用于监视和侦察 航空摄影和测量 搜索和救援任务 通信中继和环境监测 目前无人机的手动控制大部分基于视觉反馈 xff0c 所以操作环境中的障碍物会造成干扰 因此 xff0c 需要其他感官反馈 xff0c 例如触觉 xff0c
  • DB2reorg 和runstats使用

    DB2中 xff0c 如果使用alter更改表结构后 xff0c 需要执行reorg 命令消除碎片 xff0c 进行重组 xff1b 创建索引后 xff0c 需要执行RUNSTATS更新统计信息 xff0c 使索引生效 xff1b 如果修改
  • HTTP的8种请求方式及常用请求方式的解析

    一 什么是HTTP xff1f HTTP xff0c 即超文本传输协议 xff0c 是一种实现客户端和服务器之间通信的响应协议 xff0c 它是用作客户端和服务器之间的请求 客户端 xff08 浏览器 xff09 会向服务器提交HTTP请求
  • 星网宇达(惯导+IMU)设备实现自动采点

    一 创建和打开gps Road txt文件 xff0c 准备往里写数据 FILE span class token operator span p span class token operator 61 span span class t