定位引擎的设计
定位引擎是整个定位系统中最重要的部分。它负责接收各个基站发来的数据包,并计算标签的坐标。
最初的版本,我们是使用Java开发的。后来需要作为产品对外销售,Java缺少足够的安全措施,很容易就会被反编译了,我们的知识产权无法得到保护。所以,我们改为C++重写定位引擎。因为我们的客户基本上都是使用Windows服务器,所以目前定位引擎只有Windows版。在设计之初,我们考虑到跨平台,在一些重要的地方都考虑到对Linux的支持。实际上,C++版本的定位引擎在刚写好时,我们顺利编译了一个Linux版本,并在ubuntu上运行了它。
我们需要不断对引擎进行改进,增加功能,或者提升易用性。而客户基本上没有Linux上的需求,所以,我们就再未关注Linux的支持。如果您有这个需要,应该可以最容易就让定位引擎适配Linux。
定位引擎的核心是坐标的计算。我们研究了好几个算法,缺省的情况下,使用最小二乘法进行计算。这个算法速度快、准确性也高。
定位引擎的接口支持5种方式:TCP 二进制消息接口、RESTful 风格接口、TCP 文本消息接口、TCP 自定义二进制消息接口、串行文本消息接口。
因为UWB被定义为近场通讯,这意味着UWB的覆盖范围会很小。特别是无线电管理部门对UWB发送设备的信号强度有限制,如果要保证设备合规,覆盖范围会很小。另外,有些需要定位的环境比较复杂,例如有墙之类的遮挡物。总之,我们需要支持多区域定位,把一个大的场地划分为多个定位区域,每个定位区域都部署定位基站,这些小的定位区域合并在起,就组成一个完整的定位区了。
我们的定位引擎支持多区域定位。例如,正常情况下,每个定位区域的范围是100米*100米,可以把400米*400米的区域划分为“田”字型的4块小区域,相当于部署“4套定位系统”。当然,我们系统支持区域边界上的基站复用,例如“田”字正中心的位置部署一个基站,4个区域都可以共用这个基站。在“田”字的每个交叉点部署一个基站,合计9个基站,就可以达到每个定位区4个基站的效果。
在实践中,我们发现,有些地方会有固定的偏移。为此,我们开发了一个算法,对固定偏移进行纠偏。
这个算法的开发得益于我之前开发过的卫星照片纠偏。之前做GIS系统的时候,需要对从卫星照片公司购买到的卫星照片进行校正。因为地面并不是平坦的,而卫星拍照时,并不总是从目标区域的正上方拍照,总会有些偏,是从旁边的角度拍摄的。这样,照出来的照片中的物体就会有偏移,高的偏得多一些,矮的偏得少一点。我们需要的正投的影像,所以需要把那些偏移纠正回来。
DW1000芯片对时间的计算,的一个关键是它使用的晶振。虽然尽可能使用高精度高稳定度的晶振,但不同的晶振输出的频率还是会有细微的偏差;并且,石英晶振受环境影响比较大,例如电压的波动、温度的变化等等。例如有些对稳定度要求非常高的环境,使用恒温晶振,弄一个盒子把晶振包起来,使用一些电路保证盒子中的温度恒定。。。但是,这样弄成本会比较高,体积也会变大。总之,我们需要了解各个基站的时钟稳定度,所以我们写了一个程序来直观的显示这个变化。
这个程序是研发用的,不提供给用户。也用于生产中,有时,某些客户对精度要求非常高,可以通过这个程序挑选稳定度高的基站。
CPP版本的定位引擎的开发,我们使用Visual Studio作为开发环境。使用到一些第三方的库。
例如ASIO/nlohmann json/corvusoft restbed/sqlite等,这些库都是开源的,并且在其许可证许可范围。
使用CPP开发服务器端程序,最怕的就是内存泄漏。为了确定内存安全,在debug版本,我们在各个类的构造和析构函数处添加了对象跟踪计数。
我们需要确保内存中的对象是正常的。在退出程序时,我们还要确保内存中的对象都已经释放(检查对象数量是不是0)。
在定位引擎中,我们计划要添加一些功能,因为时间的原因没有完成。
- 集成管理前端。目前我们把定位引擎的管理做成一个单独的C/S项目,后端使用Java开发,通过接口与定位引擎通讯。这就导致系统对Java的依赖。我们想把Java后端所做的事,使用C++来做。为了提高灵活性,还可以集成一个lua解释器到定位引擎中,某些功能可以使用lua来进行定制。
- 增加TOF定位算法的支持。有某些场景下,TOF反而比TDOA更有优势。我们计划添加TOF的支持。
这个项目放下已经有很长时间了,刚才把备份的代码解压,再安装了一个VS2022,编译之,正常build。
下面是定位引擎的使用手册,您可以下载下来看一下它有些什么功能。