车辆自动采点

2023-05-16

一、整体思路:
车辆自动踩点需要获取千寻差分数据,差分数据有两种格式:分别是GPGGA和GRHDT,GPGGA内存在车辆经纬度定位信息,GRHDT内存在转向角信息,分别进行关键数据提取,然后将提取的数据存放在创建的gps_road.txt中
1.main.c中

/*int main(int argc,char *argv[])中的argc是输入数组argv[]的数的个数,输入的数都打印在argv[]中*/
int main(int argc, char *argv[])
{
    
    p = fopen("gps_load.txt", "w");//第一是打开的文件,第二是打开模式。w是指打开只写文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件
    //memset(tmp,0,sizeof(tmp));

    pthread_t RecvFromIMU_tid;
    pthread_t AnalysisIMU_tid;

    int ret;

    ret = pthread_create(&RecvFromIMU_tid, NULL, RecvFromIMU_pthread, NULL);
    /*pthread_create()线程的四个参数分别为:pthread_t类型的参数,线程属性,线程新创建函数,线程函数参数,无参数时设为NULL即可。有参数时输入参数的地址。当多于一个参数时应当使用结构体传入。(以下举例)
    返回值:成功返回0,不成功返回错误码*/
	if (ret != 0)//
	{
		printf("Create thread RecvFromIMU_pthread failed\n");
	}
	ret = pthread_create(&AnalysisIMU_tid, NULL, AnalysisIMU_pthread, NULL);
	if (ret != 0)
	{
		printf("Create thread AnalysisIMU_pthread failed\n");
	}
    pthread_join(RecvFromIMU_tid, NULL);
    pthread_join(AnalysisIMU_tid, NULL);

    return 0;
}

2.创建IMU数据接收线程RecvFromIMU_pthread

void *RecvFromIMU_pthread(void *args)//线程函数
{
    memset(g_RecvDataFromRTK,0,sizeof(g_RecvDataFromRTK));//接收RTK数据数组初始化
    /*pfile=fopen("LOG.txt","a");
    if(pfile==NULL){
        printf("打开文件写LOG失败\n");
    }*/
    if(IsInit==false)//bool类型,IsInit的初始值是false
    {
        if(initialize()<0)
        {
            printf("MC: 打开串口配置参数失败\n");
            return 0;
        }
        IsInit=true;//执行到这一步说明initialize()不小于0,说明打开串口配置参数成功,使bool值为true
        printf("MC: 打开串口配置参数成功\n");
    }
    //return 0;
	int nBytes_0 = 0;
	int nBytes_1 = 0;
    while(1)
    {
        usleep(100000);
        memset(&g_RecvDataFromRTK_1, 0, sizeof(g_RecvDataFromRTK_1));//准备接收串口数据,串口接收数据数组初始化
		//memcpy(g_RecvDataFromRTK_0, g_RecvDataFromRTK_1, sizeof(g_RecvDataFromRTK_1));
		nBytes_1 = read(g_fd, g_RecvDataFromRTK_1, 200);//从串口读数据,从g_fd标志位指向的串口中读数据前200位到g_RecvDataFromRTK_1中
        //printf("g_RecvDataFromRTK_1:%s\n",g_RecvDataFromRTK_1);
        //continue;
		//printf("nBytes0=%d,nBytes=%d\n", nBytes_0, nBytes_1);
		if (g_RecvDataFromRTK_1[0] == '$')//从这判断数据格式对不对
		{
            //printf("%s\n",g_RecvDataFromRTK_0);
			char *ret;
            int i;
            int gps_num = 0;
            for(i = 0;i < 200;i++)//一共可能有200个字节的数据
            {
                if(g_RecvDataFromRTK_1[i]=='*')//因为有两段数据,分别是GPGGA和GRHDT,两段数据分别有*
                {
                    gps_num++;//取出两个*之后说明有两段数据,数据段+1
                }
                if(gps_num==2)//如果有两段数据,退出循环
                {
                    break;
                }                  
            }
            if(i!=200)
            {
                process_len = i;
                //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);
				pthread_cond_signal(&gCond_SC_data);//线程信号触发
				pthread_mutex_unlock(&gMutex_SC_data);
            }							
		}
            //break;
    }
    return 0;
}

3.差分数据解析线程AnalysisIMU_pthread

void *AnalysisIMU_pthread(void *args)
{
    char localproc_SCData[200] = {0};
    int localproc_len=0;
    int num_gga=0;
    int num_dht=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_SCData数组中
        localproc_len=process_len;//接收差分数据的长度
        num_gga=0;
        num_dht=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;
        int rtk_num = 0;

        char *p_gpgga = strstr(localproc_SCData,"GPGGA");
        char *p_gpdht = strstr(localproc_SCData,"GNHDT");
        int gpgga_len = 60;
        int gpdht_len = 20;
        //printf("p_gpgga:%s\n",p_gpgga);
        //printf("p_gpdht:%s\n",p_gpdht);
        //printf("gpgga_len:%d\n",gpgga_len);
        //printf("gpdht_len:%d\n",gpdht_len);
        //continue;
        for(int i=0;i<gpgga_len;i++)
        {
            if(p_gpgga[i]==0x2c)//0x2c代表',';遍历数组,如果遍历到','的时候num_gga+1
            {
                num_gga++;
                if(num_gga == 2)//num_gga到达2的时候说明在经度位上,现在就是要把它取出来
                {
                    for(int j=i+1;;j++)
                    {
                        if(p_gpgga[j]==0x2c)//","后一位开始遍历,到下一个","为止退出循环
                        {
                            break;
                        }
                        else if(p_gpgga[j]!=0x2e)//如果不等于"."时候说明不是最后两位,说明可以把数据段取出来
                        {
                            g_Lattitude_tmp*=10;
                            g_Lattitude_tmp+=(p_gpgga[j]-48);
                        }
                    }
                    //
                }
                else if(num_gga == 4)
                {
                    for(int j=i+1;;j++)
                    {
                        if(p_gpgga[j]==0x2c)
                        {
                            break;
                        }
                        else if(p_gpgga[j]!=0x2e)
                        {
                            g_Longitude_tmp*=10;
                            g_Longitude_tmp+=(p_gpgga[j]-48);
                        }
                    }
                    //
                    //break;
                }
                else if(num_gga == 6)
                {
                    rtk_num = (p_gpgga[i+1]-48);
                    
                    break;
                }
            }
        }

        for(int i=0;i<gpdht_len;i++)
        {
            if(p_gpdht[i]==0x2c)
            {
                num_dht++;
                if(num_dht == 1)
                {
                    for(int j=i+1;;j++)
                    {
                        if(p_gpdht[j]==0x2c)
                        {
                            break;
                        }
                        else if(p_gpdht[j]!=0x2e)
                        {
                            g_Heading_tmp*=10;
                            g_Heading_tmp+=(p_gpdht[j]-48);
                        }
                    }
                    //
                    break;
                }                    
            }
        }
        g_Lattitude_tmp/=10000000000;
        g_Longitude_tmp/=10000000000;
        g_Heading_tmp/=10000;

        double lat_int,lat_fraction;
        double lon_int,lon_fraction;
        lat_fraction = modf(g_Lattitude_tmp,&lat_int)*100;
        lon_fraction = modf(g_Longitude_tmp,&lon_int)*100;
        g_Lattitude = lat_int+lat_fraction/60;
        g_Longitude = lon_int+lon_fraction/60;
        g_Heading = g_Heading_tmp;
        //printf("g_Lattitude:%lf  ",g_Lattitude);
        //printf("g_Longitude:%lf  ",g_Longitude);
        //printf("g_Heading:%lf\n",g_Heading);

        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)
            {
                //$GPFPD,2196,439607.060,266.245,0.522,0.414,32.0304055,120.9151016,16.56,-0.156,-0.004,0.002,5.136,12,27,45*4F
                fprintf(p,"$GPFPD,2196,439607.060,%lf,0.522,0.414,%lf,%lf,16.56,-0.156,-0.004,0.002,5.136,12,27,%d5*4F\n",
                g_Heading,g_Lattitude,g_Longitude,rtk_num);
                //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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

车辆自动采点 的相关文章

随机推荐

  • 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
  • 车辆自动采点

    一 整体思路 xff1a 车辆自动踩点需要获取千寻差分数据 xff0c 差分数据有两种格式 xff1a 分别是GPGGA和GRHDT xff0c GPGGA内存在车辆经纬度定位信息 xff0c GRHDT内存在转向角信息 xff0c 分别进