gps车载系统项目设计要点.docx
《gps车载系统项目设计要点.docx》由会员分享,可在线阅读,更多相关《gps车载系统项目设计要点.docx(13页珍藏版)》请在冰豆网上搜索。
gps车载系统项目设计要点
1.概要
车载终端与调度中心通讯协议。
背景:
GPS车载系统是安装在出租车上的一款集导航,调度,娱乐,远程刷卡,电话等为一体的智能移动终端设备。
此设备硬件环境为ARM9,ARM11等设备,操作系统可能为WINCE,LINUX,android等。
有了GPS车载终端和调度中心这个平台,可以最优化驾驶员和乘客的出车和求车的资源配置。
本项目为模拟GPS车载系统调度应用,使得初学者能很快了解到此项目的大概需求,为以后在实际工作中积累一点实战经验。
本项目有些应用无法模拟的地方均作了简化。
请学员们小心推敲琢磨。
另外,文中提到的通信格式(协议)通俗讲是一种封装,就像收发信件需要信封一样。
每条协议都是有加header头的,一是考虑安全,二是考虑你这条协议是干什么的,这样socket通信中的网络数据互不干扰,各自处理。
客户端和服务器端模型均采用linux+selectIO复用去实现。
2.通讯格式和消息类型
2.1通讯格式
start(0x02)
0
长度[注1]
1
2
FLAG%256
3
FLAG/256
4
消息体(body)
5
…
n
校验码[注2]
n+1
end(0x03)
n+2
注1:
长度=FLAG+消息内容+校验码(字段的长度)低位在前(小端字节)
注2:
校验码=从长度到消息体字节异或(data[0]^data[1]^…data[n])
2.2车载终端发起消息类型
FLAG
消息类型
附
0x03e0
参数读取
0X03e1
参数设置
0x03e2
驾驶员登录签到
0x03e3
驾驶员登出签退
0x03e4
请求驾驶员相片url信息
0x03e5
url请求下载驾驶员相片
0x03e6
驾驶员注册
2.3调度中心发起的消息类型
FLAG
类型
附
0x03d0
1秒的定位信息
0x03d1
业务信息处理
要求保存最大5条消息记录,客户端能模拟查询
3.消息体定义
3.1参数读取
车载终端发送(一次读取3个)
参数ID
0
参数ID
1
参数ID[注1]
2
调度中心返回(一次返回3个参数内容)
参数ID
0
参数长度(len1)
1
参数内容
2~len1
参数ID
Len1+1
参数长度(len2)[注2]
len1+2
参数内容
len1+3…
注1:
当车载终端读取参数时一次读取3个参数
注2:
有3个参数以此类推
可读取的参数列表(选前3个即可)
参数ID:
1=允许拨出电话(MAX16字节)
2=调度中心IP(4字节)
3=调度中心端口号(2个字节)
3.2参数设置
车载终端发送:
参数ID
0
参数长度(n)
1
参数数据
2~n
MDT返回,成功后需要改写数据库
结果码1-成功,0-失败)
0
参数ID:
1=允许拨出电话(MAX16字节)
2=调度中心IP(4字节)
3=调度中心端口号(2个字节)
注意:
设置IP和port时候请返回失败,目前只能设置允许拨出电话
3.3驾驶员登录签到
车载终端发送
驾驶员账号(10)
0
1
.
.
.
9
驾驶员密码(10)
10
.
.
.
19
调度中心返回
结果码[1-签到成功,0-签到失败]
0
3.4驾驶员签退
车载终端发送
消息内容空
调度中心返回,注意签退后不能下载相片了,故需要记录状态
结果码[1-签退成功,0-签退失败]
0
3.5请求驾驶员相片url信息
车载终端发送
消息内容空
调度中心返回(模拟返回mypic1.jpg和mypic2.jpg的URL)测试选2张相片即可
相片个数
0
第一张相片URL的长度
1
相片URL数据(n=后面URL字节长度)(
2
3
.
.
.
.
第二张相片的长度以此类推[注1]
.
相片URL数据(n=后面URL字节长度)(
.
注1:
相片URL长度+数据
3.6url请求下载驾驶员相片(注意:
3.5返回后3.6自动请求,不需要手动选择,是个自动请求的过程)
车载终端发送
消息内容空
调度中心返回(模拟下载mypic1.jpg和mypic2.jpg)
消息内容空
做简单模拟:
(使用127.0.0.1回路地址测试才有效),在本机中使用system(cmd)系统命令,cmd为cp-rf车载终端绝对路径调度中心路径,车载终端收到以后稍微提示下,打开文件以后会看到车载终端绝对路径下有2个图片文件,前提是调度中心有2个图片文件。
3.7驾驶员登录签到
车载终端发送
驾驶员账号(10)
0
1
.
.
.
9
驾驶员密码(10)
10
.
.
.
19
调度中心返回(成功则写到数据库中(模拟用配置文件))
结果码[1-注册成功,0-注册失败]
0
3.8一秒的定位信息(模拟来自美国全球卫星GPS定位数据)
调度中心发送(模拟每秒发送,数据帧$GPRMC中只修改秒数,从1-5秒循环发送(把缓冲GPS数据放入数组中,共5组数据),此处去掉GPS本身的校验)
参考数据:
$GPRMC,100119.999,A,2236.8226,N,11403.7299,E,0.62,120.87,220506,,**(详解见下文)
车载终端收到即解析数据,不作返回
GPS解析知识
提取定位数据
GPS接收机只要处于工作状态就会源源不断地接收GPS导航定位信息。
把数据放入缓存发送到车载终端进程处理,在没有进一步处理之前缓存中是一长串字节流,这些信息在没有经过分类提取之前是无法加以利用的。
因此,必须通过程序将各个字段的信息从缓存字节流中提取出来,将其转化成有实际意义的。
同其他通讯协议类似,对GPS进行信息提取必须首先明确其帧结构,然后才能根据其结构完成对各定位信息的提取。
在本文中,其接受的数据主要由帧头、帧尾和帧内数据组成,根据数据帧的不同,帧头也不相同,主要有"$GPGGA"、"$GPGSA"、"$GPGSV"以及"$GPRMC"等。
这些帧头标识了后续帧内数据的组成结构,各帧均以回车符和换行符(0X0D、0X0A)作为帧尾标识一帧的结束。
对于通常的情况,我们所关心的定位数据如经纬度、速度、时间等均可以从"$GPRMC"帧中获取得到,该帧的结构及各字段释义如下,
数据丰富的最典型情况,均为ASCII字符数据。
$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>*hh
<1> 当前位置的格林尼治时间,格式为hhmmss.sss
<2> 状态, A 为有效位置, V为非有效接收警告,即当前天线视野上方的卫星个数少于3颗。
<3> 纬度, 格式为ddmm.mmmm格式不定长,例如:
3111.4364
<4> 标明南北半球, N 为北半球、S为南半球
<5> 经度,格式为dddmm.mmmm 格式不定长,例如:
12125.1027
<6> 标明东西半球,E为东半球、W为西半球
<7> 地面上的速度,范围为0.0到999.9
<8> 方位角,范围为000.0到 359.9 度
<9> 日期, 格式为ddmmyy
<10> 地磁变化,从000.0到 180.0 度(不考虑)
<11> 地磁变化方向,为E 或 W(不考虑)
数据缺失的最典型情况将是:
$GPRMC,<1>,<2>,,,,,,,,,*hh
<1> 当前位置的格林尼治时间,格式为hhmmss.sss
<2> 状态, A 为有效位置, V为非有效接收警告,即当前天线视野上方的卫星个数少于3颗。
数据将会出项缺失,时间回复到出厂时间,定位情况为V,(不定位警告)。
至于其他几种帧格式,除了特殊用途外,平时并不常用,虽然接收机也在源源不断地向主机发送各种数据帧,但在处理时一般先通过对帧头的判断而只对"$GPRMC"帧进行数据的提取处理。
如果情况特殊,需要从其他帧获取数据,处理方法与之也是完全类似的。
由于帧内各数据段由逗号分割,因此在处理缓存数据时一般是通过搜寻ASCII码"$"来判断是否是帧头,在对帧头的类别进行识别后再通过对所经历逗号个数的计数来判断出当前正在处理的是哪一种定位导航参数,并作出相应的处理。
下面就是对缓存Data中的数据进行解帧处理的主要代码,
例如某数据:
$GPRMC,100119.999,A,2236.8226,N,11403.7299,E,0.62,120.87,220506,,**
' 100119.999 --十分秒(格林威治时间)
' 2236.8226,N --北纬坐标(2236.8226) 2236.8226,S ----南纬坐标
' 11403.7299,E--东京坐标(11403.7299) 11403.7299,W ----西京坐标
' 0.62 --gps的移动速度
' 120.87 --地面的方位角
' 220506 --日期
//GPS数据结构
typedef struct _GPSData
{
char date[15] ; //Gps数据日期
char time[15] ; //Gps数据时间
char latitude_type; //纬度类型,北纬,南纬
char latitude[15] ; //纬度值
char longitude_type; //经度类型,东经,西经
char longitude[15] ;//经度值
char speed[6];//速度
//char starNum; //卫星数目
char IsValid;
}GPSData,*PGPSData;
/*point为所有的帧数据,buflen为帧长度,要求您写的AnalyGpsData过滤掉其他帧,只处理$GPRMC数据*/
void AnalyGpsData(char *point, int bufLen)
{
int i,err = 0,nDotNum = 0;
memset(&m_gpsCurData,0,sizeof(m_gpsCurData));//注意数据结构的初始化
char buf[16] = {0}; //储存','到','之间的数据
while
(1)
{
if(*(point) == '$')
{
//$GPRMC
if((*(point) == '$')&&(*(point+1) == 'G')&&(*(point+2) == 'P')&&(*(point+3)== 'R')&&(*(point+4) == 'M')
&&(*(point+5) == 'C'))
{
while
(1)
{
i = 0;
while(*point !
= ',')
{
buf[i] = *point;
i++;
point++;
}
point++;
buf[i] = '/0';
nDotNum++;
switch(nDotNum)
{
case 2:
memcpy(m_gpsCurData.time,&buf[0],strlen(buf));
break;
case 3:
// Valid(A)/InValid(V)
if(buf[0] == 'V')
{
err = 1;//没有定位
}
m_gpsCurData.IsValid = buf[0];
break;
case 4:
// 纬度:
22.342551
if(err == 0)
{
memcpy(m_gpsCurData.latitude,&buf[0],strlen(buf));
}
break;
case 5:
//南北纬
//if( (buf[0] !
= 'N') && (buf[0] !
= 'S') ) goto Wrong;
if(err == 0)
{
m_gpsCurData.latitude_type = buf[0];
}
break;
case 6:
// 经度:
114.080338
if(err == 0)
{
memcpy(m_gpsCurData.longitude,&buf[0],strlen(buf));
}
break;
case 7:
//东西经
if(err == 0)
{
m_gpsCurData.longitude_type = buf[0];
}
break;
case 10:
// 150805:
2005-8-15 ddmmyy
memcpy(m_gpsCurData.date,&buf[0],strlen(buf));
goto Wrong;
default:
break;
}
}
}
}
goto Wrong;//other sentence
}
Wrong:
return;
//delete[]buf;
}
到此为止,已将时间和经纬度信息提取到GPS结构数组GPSData中的各个变量中去,后续的处理可根据该结构中存储的数据作出相应的处理。
比如:
请继续判断,是否定位;根据方位角判断目前车辆定位在是正东,正西,正南,正北,东南,东北,西南,西北;请对GPS格林尼治时间(世界时间)进行+8转化为北京时间进行平年闰年月份等方面考虑,并显示出星期几。
3.9业务处理信息
调度中心发送:
业务ID
0
1
2
3
要车时间[年,月,日,时,分,秒][BCD]
4
5
6
7
8
9
内容长度
10
信息内容
11
…
n
车载终端不做返回(收到即保存到文本中,最大能保存5个文本,需要保存业务ID,要车时间,信息内容)