引言
随着汽车行业的快速发展,全球能源问题、环境问题和安全问题日益严重,解决问题的方式之一是建立汽车移动物联网通信平台。汽车移动物联网分为感知层、网络层和应用层三层。由感知层获取采集车辆内部和外部的各种信息。网络层主要是GPRS/3G无线网络,将感知层得到的信息通过GPRS/3G无线网络发送到上位机,应用层主要是接收网络层传输过来的数据并进行处理[1],图1为车联网三层架构图。
系统的应用层包括上位机监控中心和Android手机版本的客户端,具备六大功能模块:车辆基本信息、远程监控、远程控制、远程故障诊断、寻车辅助、驾驶员疲劳状态等。
上位机监控中心作为Socket服务器,要求具备公网IP和端口,可以被外网访问。车载终端模块作为Socket客户端,当Socket连接建立之后,由车载终端将车辆的信息通过GPRS无线网络传给PC机,同时上位机监控中心也可以主动下发一些指令,查询车载终端的状态,要求车载终端上传相关信息。
1 PC机监控中心设计
1.1 Socket通信设计
Socket分为服务器和客户端两部分,上位机作为服务器,使用VB中的Winsock控件,通过Socket实现与车载终端和手机客户端的通信。
服务器端Winsock在接收客户端连接之后,会检测Winsock1.State的值,如果Winsock1没有关闭的话则会将Winsock1关闭。当服务器与客户端连接成功之后,服务器便开始接收客户端的数据并且进行处理,同时还可以向客户端发送数据和命令。
当打开了主窗体时,在Private Sub Form_Load()事件中自动加载Socket的监听和连接,并且当点击了各个功能模块的按钮时,上位机会通过Socket向车载终端下发查询或者控制指令。
在PC机上位机程序中,需要设计两个Socket连接,一个是用来与车载终端建立连接,另外一个是用来与Android手机建立连接。上位机Winsock1收到车载终端发送的数据之后,会进行处理并且存入到后台数据库。Android手机通过Winsock2从上位机获取数据。当多个车载终端同时连接监控中心时,可以采用动态加载和卸载Winsock的方式,同一个端口监听不同的连接请求,根据客户端的IP地址来区分车载终端,端口号相同但连接的Index不同。
1.2 电子地图的加载与纠偏
为了能够在电脑上直观地看到车辆的位置,在上位机设计了一个地图加载界面,通过GPRS传送的经度和纬度信息,显示出车辆的当前位置。由于传统的地理信息系统(GIS)技术复杂,建设和维护的成本高,本次设计采用调用在线地图API(应用程序接口)的方式来实现地图的加载,这样一方面省去了繁琐的测绘和地图编制工作,另一方面也保证了地图更新的实时性,地图提供商会定期更新地图,提高定位的有效性和精度[2]。
通过VB中的webbrowser控件,来加载一个后缀名为.htm的静态网页文件,可以实现电子地图的加载。在静态网页中,编写一个JavaScript函数,就可以在百度地图上通过经度和纬度进行定位,并且可以实现电子地图的放大、缩小和移动。
由于GPS的坐标与百度地图加载的坐标是不匹配的。国际上采用的是WGS-84标准的地心坐标,国内发行的地图必须要使用国家测绘局规定的GCJ-02进行加密,而百度地图在此基础上还使用百度公司的BD-09进行二次加密,因此GPS采集的经纬度和百度地图并不匹配,需要进行坐标接口转换,百度地图也提供了进行坐标转换的API接口函数。
在VB中利用webbrowser控件调用电子地图并且实现坐标转换的语句如下:
WebBrowser1.Document.parentWindow.execScript "map.panTo(new BMap.Point( " & jingdu & "," & weidu & "))", "javascript"
WebBrowser1.Document.parentWindow.execScript"map.addOverlay(new BMap.Marker(new BMap.Point( " & jingdu & "," & weidu & ")))", "javascript"
WebBrowser1.Document.parentWindow.execScript "BMap.Convertor.translate(new BMap.Point( " & jingdu & "," & weidu & "),0,translateCallback)", "javascript"
在上面的语句中,使用WebBrowser1.Navigate App.Path & "\BaiduMap.htm"这个语句来加载已经编写好的“BaiduMap.htm”地图文件。调用坐标转换函数时使用了new BMap.Point函数来新建坐标点,translateCallback为在静态网页文件中编写的函数,该函数可以实现将指定点移到地图中心、清除标注以及在指定坐标位置添加地标[3]。
1.3 后台数据库的设计
在VB中可以直接嵌入开发Access数据库,通过“外接程序”中的“可视化数据管理器”可以直接创建Access数据库,也可以加载或导入其他类型的数据库。在VB中与数据库的连接通常是使用ADO来实现的,在VB中操作后台数据库的步骤如下[4]:
(1)创建或导入数据库,与数据库建立连接。
(2)根据相应的命令读取数据库中的数据,并且在数据绑定控件中显示。
(3)对获取的对象进行增删改查操作,并且将更新后的数据重新存入数据库。
在数据库的表格中,设计的字段主要有车主、车牌号、车型、经度、纬度、速度、前左车门、前右车门、后左车门、后右车门、前端盖、后端盖、故障代码和驾驶员疲劳状态等,在收到了GPRS发送过来的数据之后,根据协议进行解码,将其中的数据分别存入对应的数据库当中。向数据库中新增数据的代码如下:
本文引用地址:http://www.eepw.com.cn/article/245925.htm
Adodc1.Recordset.AddNew '将数据写入数据库
Adodc1.Recordset("车主") = chezhu
Adodc1.Recordset("车牌号") = chepaihao
Adodc1.Recordset("车型") = chexing
. . . . . .
Adodc1.Recordset.Update
上面的chezhu、chepaihao、chexing等变量都是获得了车载终端数据的全局变量,利用这种方式可以将数据存入到数据库对应的字段当中,便于查询、使用和保存。
2 Android手机客户端设计
2.1 Android中Socket通信设计
Android中提供了一个Socket的类,存在于“java.net.Socket”包中。首先要设定连接服务器的公网IP以及端口号,同时以输入流InputStream()的形式来获取从服务器传过来的数据,然后从输入流中读取相应的数据存入缓冲区,最后读取缓冲区即可以得到所需要的数据。把接收到的数据存在一个字符串里面,根据Android手机客户端和PC上位机的协议进行数据的解码,再把解码后的数据存入到相应的字段当中,比如经度、纬度、速度、驾驶员疲劳状态等等。
使用手机也可以向PC机发送数据和指令,比如点击了“车辆监控”按钮时,就需要向PC机发送指令,再通过PC机来控制车辆,从而达到手机监控车辆的效果。当手机需要向PC机发送数据时,建立Socket连接之后,是通过输出流来实现的,先定义好所要发送的数据,再用outputStream.write()语句来将数据发送到Socket服务器。
由于Socket在连接通信的时候有可能会出现异常,所以系统要求加入用来捕捉和处理异常的try-catch语句。程序运行正常时,执行try{}里面的代码;当出现异常时,执行catch里面的语句捕捉和处理异常。Android中Socket通信的部分代码如下。
try{
Socket Socket = new Socket("125.216.144.177",8091); //实例化Socket
InputStream indata = Socket.getInputStream(); //获得从服务器传过来的数据
byte[] buffer = new byte[indata.available()]; //缓冲区
indata.read(buffer); //读取缓冲区
String msg = new String(buffer); //转换字符串
System.out.println(msg); //将得到的数据进行输出
String[] arr= msg.split(","); //以“,”分割收到的数据,存入arr[]数组当中
OutputStream outputStream = Socket.getOutputStream(); //获得输出流,向服务器发送数据
byte[] buffer2 = new byte[1111] ; //定义要发送的数据
outputStream.write(buffer2, 0, 6); //开始发送数据
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace(); }
2.2 Android中电子地图的加载与纠偏
近几年随着Android操作系统的兴起,越来越多的地图供应商都提供了Android地图的SDK(软件开发包),在Android中开发地图加载的流程如下[5]:
Android程序在开发地图时,需要在“AndroidManifest.xml”列表中添加多个应用权限,保证电子地图能够正确加载。
然后进行初始化设置,在“SetupMap”函数中,需要设置地图视图、设置缩放尺度、将指定坐标设置为地图中点。
“MapView”类的“setTraffic”方法可以设置显示地图视图的模式,地图视图的模式有卫星图map.setSatellite(true)、一般地图map.setTraffic(true)、街道图map.setStreetView。“MapController”类的“setZoom”方法可以控制地图的缩放尺度。由全球地图(1)到街道地图(21),数值越大地图细节越详细。
Android通过“Geopoint”类来定义坐标,“Geopoint”接受的两个参数分别是“纬度”、“经度”值,需要以整数来表示。“Geopoint”接受的纬度和经度手机通过Socket从上位机获取,然后通过实例化GeoPoint ()对象,在GeoPoint ()输入纬度和经度即可以实现地图的加载[6]。
GeoPoint point = new GeoPoint((int)(weidu),(int)(jingdu));
无论是Google地图还是百度地图,GPS坐标直接输入加载处理的位置是有偏差的,论文使用百度地图提供的在线API坐标转换接口来实现纠偏,其语句为
GeoPoint point2 =CoordinateConvert.bundleDecode(CoordinateConvert .
fromWgs84ToBaidu(point));进行转换之后可以很好的解决坐标偏移的问题,测试结果表明定位误差在5米以内。
为了在地图上标示车辆所在的位置,需要添加一个定位图标。在Android电子地图中属于覆盖物,所有的覆盖物都继承“Overlay”类,本次设计自定义一个CustomItemizedOverlay子类,继承ItemizedOverlay类,用来实现标注定位图标和定位文字的功能。
3 系统的测试与结论
在设计好监控中心和手机客户端之后,配合硬件进行测试,监控中心要具备公网IP,图4和图5为监控中心的部分界面展示,图6为Android手机客户端界面。
从以上测试结果可知,本次车联网系统的设计达到了预期目标,系统总体运行流畅,上位机监控中心和Android手机能够正确显示车辆的基本信息、精确显示车辆的位置、对车辆进行监控和控制、警示驾驶员是否疲劳等,便于车辆的管理、监控、调度、远程诊断等,为我国的智能交通行业的发展提供有力的参考。