1 文档的学习
这段时间主要在看开发文档,尝试去分析开发文档中关于每个函数的相关信息。
凭借我丰富的词汇量某文档软件的划词翻译,大致了解了GeoCom开发的相关内容:GeoCom的开发总共分为如下的几个模块,我这里按照文档的顺序进行编排。
1.1 AUS:(Alt User)
主要包括"Shift + User"按钮后面的相关函数。
1.2AUT(Automatisation)
自动化。主要包含直接对仪器本身的操控,自动对准棱镜,开启超级搜寻(Power Search)等等。
1.3 BAP(Basic Applications)
主要功能。主要包含设置测量棱镜的目标参数,配置测量方式,测量当前仪器的参数和目标棱镜与仪器的距离等。
1.4 BMM(Basic Man Machine)
基本机器控制。说的是基本机器控制,但是这个里面的东西也太基本了,总共就三个函数,还全是控制仪器发出警告(蜂鸣声)的函数
1.5 COMF与COM(Communication)
数据交流。但是这两个我没弄太明白有什么区别,看图中的内容好像COMF是联系GeoCOM开发客户端(PC,Android等)和GeoCom服务端(仪器)的桥梁。官方给出的含义的描述是,前者主要控制一些基础的交流参数(例如初始化GeoCom接口),后者主要是一些对仪器的基本操作(待机开机,检查仪器设备型号)。前者不能通过ASCII命令行去控制,后者可以。有比较了解的读者可以在评论区指导一下。
1.6 CSV(Central Services)
中央服务。主要是提供关于一些一起的基础数据(例如软件版本,出厂编号,剩余点亮,温度,时间等)感觉这个可以配合温度湿度来修改仪器的一些参数,减少测量误差。
1.7 CTL(Control task)
任务控制。这个在开发文档里面没有提及相关的内容,也没有相关的接口函数。我猜测可能与多线程有关。
1.8 EDM(Electronic Distance Meter)
激光测距。主要用来通过测量激光的相位来计算距离。在BAP模块中有部分功能用到了该模块的功能。
1.9 FTR(File Transfer)
文件传输。名副其实,用来传输文件的模块。
1.10 IMG(Image Processing)
图像处理和加工。主要是处理图像的功能,但是单看函数好像只有对图像的下载和上传,与FTR模块的功能类似。可能可以开发为实时的图传?
1.11 SUP(Supervisor)
管理。只有一个设置函数:设置电源管理模式,在电源即将耗尽时是切换为关机还是待机。
1.12 TMC(Theodolite Measurement and Calculation)
经纬仪的测量与计算。这里面的功能比较多,我还暂时没有看完,大致上包括测量棱镜相对的坐标等等。
英文文档读起来实在有点费劲,我在网上找到了一篇相关的中文文档,具体的网址好像找不到了。那个里面介绍了一下整个测量的流程,这个文档也帮了我不少的忙。
2 通过接口自动测量的流程
中文文档中定义了整体测量的一个流程,我根据流程去寻找相应的接口和命令。一个相对比较完整的流程如下:
2.1初始化GeoCom
首先对GeoCom接口的初始化,然后才能对通过GeoCom调用指令(ASCII命令不用进行)
2.2初始化通讯接口
开放通讯接口,然后GeoCom服务端才能接受到指令(ASCII命令不用执行)
2.3将仪器转到指定方向
2.4 精密照准目标
2.5 执行测距动作
2.6 获取角度和距离的测量数据
3 遇到的一些问题
首先是运行的命令顺序的问题,仪器必须要等待一系列必要操作完成之后才能进行测距操作:在转到指定的位置之后才能执行查找目标的操作,在查找目标之后才能进行精准的测距等。在这里我的方案是创建一个命令集合,在收到前一个发送命令的响应之后,根据返回的状态码(RC)决定如何运行下一个命令。
然后是考虑怎么使用蓝牙来控制了。uni-app的蓝牙只能搜索到低功耗蓝牙设备,而且会搜索到很多没有名字的蓝牙设备,也不知道具体的原因。思考再三使用了前辈的BlueToothTool.js,本质上是对native.js的一个封装。但是前辈封装的主要是他之前的那个项目,有些参数是写死的,导致我这边在测试过程中遇到很多问题,具体问题如下:
3.1 部分命令成功发送,但是没有响应命令
在上一个日志里面我有提到过发送命令但是没有回执的问题是命令发送的格式不正确,但是这次再次出现了这种情况。比较诡异的是,只有部分命令发送之后没有响应,而且在下一次发送时会同时接受到两次响应命令。这会直接导致我之前这种命令串会停止发送的情况。在排除掉仪器部分的问题之后,我重新去看了一眼源码。
/**
* 发送数据
* @param {String} dataStr
* @return {Boolean}
*/
function read(msgCount) {
//clearInterval(setIntervalId);
let dataArr = [];
let hasdata = false;
let datacount = 0;
let block = false;
let reading = false;
//setIntervalId = setInterval(doReadData, 100);
var mcount = 0;
let start = new Date().getTime();
let last = start;
//注意到这行代码,只会读取3s
while ((new Date().getTime()) - start < 3000) {
let now = new Date().getTime();
if (now - last > 200) {
last = now;
let bres = doReadData();
if (bres) {
mcount++;
if (mcount == msgCount) {
break;
}
}
}
}
function doReadData() {
//console.log('模拟线程:'+t);
//setTimeCount++;
if (hasdata) return false;
if (block) return false;
while (invoke(btInStream, "available") != 0) {
hasdata = true;
let data = invoke(btInStream, "read");
dataArr.push(data);
}
if (hasdata && invoke(btInStream, "available") == 0) {
block = true;
hasdata = false;
//var strResponse = String.fromCharCode.apply(String, dataArr);
//strResponse = strResponse.replace('\r','').replace('\n',';');
//console.log('输出结果_E:' + strResponse);
options.readDataCallback && options.readDataCallback(dataArr);
dataArr = [];
block = false;
return true;
}
return false;
}
}
/**
* 发送数据
* @param {String} dataStr
* @return {Boolean}
*/
function sendData(dataStr) {
if (!state.bluetoothEnable) {
shortToast("蓝牙设备未开启!");
return;
}
if (!state.isBluetoothConnected) {
shortToast("蓝牙设备未连接!");
return;
}
if (!btOutStream) {
shortToast("创建输出流失败!");
return;
}
try {
console.log(dataStr);
let bytes = invoke(dataStr, 'getBytes', 'ASCII');
// let bytes = strtoascii(dataStr);
btOutStream.write(bytes);
//注意到这行代码,会读取两串数据
read(2);
} catch (e) {
//alert('发送失败!'+JSON.stringify(e));
return false;
}
return true;
}
总之找到了原因:仪器的部分操作(例如将仪器精准的转移到某个方位角)所耗时间过长时,会导致消耗的时间大于tool.js中的监听时间,从而导致没有拿到响应,而将监听时间延长至10s后成功解决。这也能够解释为什么在第一次没有收到响应之后发送一个其他的指令会收到两次响应的诡异情况。
结果改正该问题后每一次请求后都会等待10s,发现是因为在发送数据之后会读取两串命令(或者发送之后收到的间隔大于指定的时间间隔),然后才会进行收到命令的回调函数。
3.2 仪器定位的问题
以上问题解决之后,就是简单无聊的数据处理了。仪器测得的数据(2082指令)是相对坐标,需要使用矩阵换算的方式来转换为绝对坐标。需要注意的是这个相对坐标原点位于仪器所垂直水平面投影到地表的位置,而不是仪器本身的位置,因此需要扣除一个仪器的当前高度(原谅我实在是没有找到直接设置仪器高度的指令)。解决完数据处理之后进行了一次较为成功的测试。
随后就发现了存在的问题:当两个棱镜距离很近时,会导致精密照准目标(9037指令)出现紊乱,两个棱镜锁定出现问题。如果理论坐标十分准确,转到指定位置后仪器的十字准星准确地定位到棱镜中,则不会出现该问题。但是如果涉及到监测位移这种理论位置本身就不准确,而且指向的目标存在两个距离很近(不是空间含义的距离,是视角含义的距离)的情况,会导致锁定出现紊乱。
4 之后的探索路线
其实我个人不太喜欢使用蓝牙去连接和控制。首先设备的蓝牙距离很近,如果很多指令要靠蓝牙去连接的话,要么每次执行测量操作需要一个人手持设备站在现场,要么将带有蓝牙的设备放到传感器附近,然后通过网络来对这个蓝牙设备发送指令。其次是不太符合目前物联网的大环境,仪器本身是带有RS232接口的,也可以外接网络串口设备。
这样一来仪器的可操作性就比较强了,既可以通过客户端,也可以通过网页、app、甚至小程序来控制仪器。不过还是不太清楚能否通过网络来发送ASCII指令,如果可行的话不出意外下一篇日志应该是围绕这个功能来记录了,如果不行的话还是回来继续我的蓝牙开发。