简介:本资源是徕卡TS30、TS50系列测量机器人Geocom二次开发的权威中文技术指南,面向测绘工程师、自动化测量系统开发者及高校相关专业研究人员,解决Geocom接口理解门槛高、官方英文文档阅读困难、C/C++与VBA调用协议不清晰等实际开发痛点。压缩包含1个1.49MB的DOCX文档,结构完整,覆盖GEOCOM通信原理、ASCII协议语法与数据类型定义、C/C++及VBA双语言函数调用规范、基础编程框架、TPS1200仪器操作方式及常见通信错误排查等内容,目录层级清晰,示例代码与协议说明紧密结合,便于边学边练。目前已有2426人学习下载,是开展高精度工程测量自动化、定制化数据采集与实时分析等场景二次开发不可或缺的实操型参考资料。
1. GEOCOM 不是“API 文档”,而是测量机器人通信的「协议-驱动-状态机」三重黑匣子
你写完一段 C++ 代码调用COM_OpenPort(),串口灯亮了,COM_NullProc()返回0,你以为通信通了——结果一发AUT_Search(),望远镜纹丝不动,仪器面板上连 ATR(自动目标识别)指示灯都不闪。你查日志、换线、重装驱动,折腾两小时才发现:根本不是端口问题,而是你没调用CSV_GetInstrumentName()触发内部状态机初始化,GEOCOM 库在底层悄悄把所有 AUT 模块的命令队列给静默丢弃了。
这不是玄学,是 GEOCOM 的真实工作逻辑:它表面是一套 C 函数库,实则是嵌入式设备侧固件与 PC 侧开发环境之间,一套高度耦合的协议解析器 + 硬件状态同步器 + 命令事务调度器。TS30/TS50 系列的主控 MCU 运行着精简实时系统,其通信模块不接受裸 ASCII 命令流;它只认 GEOCOM 封装后的二进制 RPC 包,且每个包必须携带当前会话的上下文令牌(Session Token),而这个令牌的生成、校验、续期,全由CSV_*和COM_*系列函数在后台协同完成。中文说明书里反复出现的 “初始化 GeoCOM”、“获取仪器版本”、“检查通信” 等步骤,不是形式主义的 Hello World,而是强制你参与这套状态机的握手流程。跳过它,你的AUT_Search()就像往关机的路由器发 ping —— 物理链路通,但协议栈根本没加载。这份 2019 年发布的中文说明书,之所以至今仍是 TS30/TS50 二次开发不可绕过的起点,正因为它把这套隐性机制,用最直白的函数调用顺序和错误码映射,钉死在纸面上。搞懂它,你才真正拿到打开测量机器人控制权的物理钥匙,而不是在 API 表面滑动的幻觉。
2. ASCII 协议:不是字符传输,而是 GEOCOM 的「指令编解码层」与「错误隔离边界」
GEOCOM 支持两种通信模式:ASCII 协议与二进制函数调用(C/C++/VBA)。很多开发者误以为 ASCII 是“低级原始模式”,二进制才是“高级封装”。错。ASCII 协议恰恰是 GEOCOM 最核心的指令语义层,而 C 函数库只是它的语法糖外壳。理解这一点,是避开 80% 通信失败的根本。
2.1 ASCII 协议的本质:带校验的状态指令帧,而非字符串流
翻开说明书第 2.3 节 “ASCII 协议语法”,它定义的不是普通串口通信格式,而是一套严格的状态机指令帧:
<STX><CMD><PARAMS><ETX><CHK><STX>(0x02):帧起始,通知固件新指令到来;<CMD>:2 字节大写英文命令,如"AU"(AUT 模块)、"ED"(EDM 模块);<PARAMS>:参数区,必须为 ASCII 可见字符,禁止空格、制表符、控制字符;数值用十进制字符串表示(如"12345"),布尔用"1"/"0";<ETX>(0x03):帧结束;<CHK>:1 字节异或校验和(从<STX>到<ETX>所有字节异或)。
关键点在于:<PARAMS>区不解析数据类型。"12345"在AUT_ReadTol中是微米级公差值,在BAP_MeasDistanceAngle中却是水平角 Hz 的秒值。它的语义完全由<CMD>决定,固件收到"AU01"(AUT_ReadTol)后,才按 AUT 模块预设规则将"12345"解析为int32_t公差值。这解释了为什么说明书 3.2.1 节强调:“ASCII 协议中的数据类型由函数名隐式定义,而非参数字符串本身”。
2.2 为什么 C 函数库必须封装 ASCII 帧?—— 防止状态污染
看一个典型 C 调用:
int tol = 5000; // 5mm 公差 int ret = AUT_ReadTol(&tol);表面上是读取,实际 GEOCOM 库干了三件事:
- 构造 ASCII 帧:拼出
"AU015000\x03\xXX"(XX为校验和); - 插入会话令牌:在帧头前插入 4 字节 Session ID(来自
CSV_GetInstrumentName()初始化); - 阻塞等待响应:发送后进入轮询,直到收到
"AU01OK5000\x03\xYY"或"AU01ERR01\x03\xZZ"。
若你绕过 C 库,直接用串口工具发"AU015000\x03\xXX",会得到"AU01ERR07"(错误码 07 = 无效会话)。因为固件校验时发现帧无 Session ID,直接拒收。C 库的“封装”,本质是维护会话状态的代理,而非简化语法。这也是说明书 3.3.2 节强调“基本 GeoCOM 应用框架”的原因:COM_Init()→CSV_GetInstrumentName()→AUT_Init()这个链条,是在构建并绑定一个完整的会话上下文,缺一不可。
2.3 ASCII 帧的调试价值:定位错误的黄金标准
当AUT_Search()失败时,不要只看 C 函数返回值。用串口监听工具(如 RealTerm)捕获实际发出的帧:
- 正常帧:
<STX>AU08<ETX><CHK>(AU08= AUT_Search) - 错误帧:
<STX>AU080000<ETX><CHK>(多发了0000参数,固件解析失败)
说明书第 3.7 节 “常见的通信错误” 列出的ERR01(命令未识别)、ERR03(参数格式错误)、ERR07(会话无效),全部对应 ASCII 帧层面的解析失败。这是比 C 层返回值更底层、更确定的诊断依据。我曾帮某高校团队解决“搜索总超时”问题,抓包发现他们用 VBA 调用AUT_Search时,VBA 自动在参数后加了\0,导致帧变成AU08\x00<ETX>,固件卡在校验阶段直接丢弃——这种错误,C 层函数返回0(成功),但硬件毫无反应。
提示:调试时务必关闭 C 库的自动重试机制(说明书未明说,但
COM_SetTimeout()设为 0 可禁用)。否则你看到的可能是重发帧,掩盖原始错误。
3. 状态机设计:TS30/TS50 的硬件模块如何被 GEOCOM “虚拟化”为可编程对象
TS30/TS50 不是通用计算机,其内部由多个专用硬件模块组成:ATR(自动目标识别)、EDM(电子测距)、BMM(人机界面)、IMG(图像处理)等。GEOCOM 的高明之处,在于它没有暴露这些模块的寄存器地址或中断向量,而是将它们抽象为带生命周期的状态机对象。每个模块(如 AUT、EDM、BAP)的函数族,本质是操控该对象的状态转换。不理解这点,就会写出“命令发了但没生效”的代码。
3.1 AUT 模块:一个三态有限自动机(FA)
AUT(Automatic Target Recognition)模块的状态机在说明书第 7 章有完整映射:
- Idle(空闲):望远镜静止,ATR 关闭。此时可调用
AUT_Search()启动搜索。 - Searching(搜索中):ATR 激活,扫描 PowerSearch 窗口。此时
AUT_Search()会返回ERR05(操作进行中),必须等待AUT_PS_SearchNext()完成或超时。 - Tracking(跟踪中):目标锁定,望远镜跟随移动。此时
AUT_Search()会返回ERR06(目标已锁定),需先调用AUT_StopTracking()退出。
关键陷阱:AUT_Search()不阻塞。它只是向固件发送“启动搜索”指令,立即返回。真正的搜索过程在后台异步执行。说明书 7.4.8 节AUT_PS_SearchNext()的存在,正是为了让你轮询搜索进度。如果你在AUT_Search()后立刻调用AUT_ReadTol(),大概率读到的是旧值,因为搜索尚未开始。
3.2 EDM 模块:距离测量的“准备-触发-读取”三阶段
EDM(Electronic Distance Measurement)的测量流程在说明书第 12 章体现为严格时序:
- 准备阶段:调用
BAP_SetEDMType()设置测距模式(精测/粗测/跟踪),BAP_SetPrismType()设置棱镜常数。这些设置写入固件配置寄存器,但不触发测量。 - 触发阶段:调用
BAP_MeasDistanceAngle()。此函数发送BAP命令帧,固件启动 EDM 发射激光、接收反射信号、计算相位差。 - 读取阶段:
BAP_MeasDistanceAngle()阻塞等待,直到 EDM 完成测量并返回 Hz/V/距离值。若超时(默认 10 秒),返回ERR04。
这里的设计动机很清晰:TS30/TS50 的 EDM 硬件是模拟电路+高速 ADC,一次测量耗时 200~800ms(取决于模式)。GEOCOM 强制分离“配置”与“执行”,避免你在配置未完成时就触发测量,导致硬件状态冲突。说明书 8.3.12 节特别注明:“BAP_MeasDistanceAngle()是唯一能获取实时测量值的函数”,暗示其他函数(如BAP_GetTargetType())只读配置,不读数据。
3.3 CSV 模块:全局状态中枢,所有模块的“心跳监护者”
CSV(Central Service)模块在说明书第 11 章被称作“中央服务”,它并非独立硬件,而是固件的全局状态管理器。CSV_GetDateTime()、CSV_GetSWVersion()等函数,读取的是固件运行时的共享内存区。更重要的是,CSV_CheckPower()返回的电源状态,直接影响 AUT 和 EDM 的行为:
- 若
CSV_CheckPower()返回POWER_BATTERY_LOW,AUT 搜索会自动降频,EDM 测距精度降低; - 若
CSV_GetIntTemp()超过 50°C,固件可能拒绝AUT_Search(),返回ERR09(温度过高)。
这就是为什么说明书强调“初始化 GeoCOM”必须以CSV_GetInstrumentName()开头——它不仅是获取名字,更是向固件申请一个会话句柄,并同步获取当前全局状态快照。后续所有模块函数,都隐式依赖这个快照中的电源、温度、固件版本信息。跳过它,AUT 可能在低温下无法启动(因固件认为电池不足),而你还在查 ATR 镜头是否脏了。
注意:
CSV_GetDateTimeCentiSec()(毫秒级时间戳)是调试时序的关键。我曾用它定位一个“测量值延迟 2.3 秒”的 bug:发现是BAP_MeasDistanceAngle()返回后,用户代码又调用了三次CSV_GetDateTime(),每次耗时 700ms(因串口波特率设太低),导致整体延迟。优化波特率后,延迟降至 20ms。
4. 避坑:TS30/TS50 二次开发中 5 个血泪经验总结
以下是我在多个工程现场(某跨平台监测系统、某隧道施工导航 Demo)踩过的坑,每一条都对应说明书中的具体章节和错误码,绝非泛泛而谈。
4.1 现象:AUT_Search()总是返回ERR01(命令未识别)
原因:调用前未执行AUT_Init(),或AUT_Init()返回失败但被忽略。AUT_Init()在说明书 7.4.1 节定义,它不仅初始化 AUT 模块,还校验 ATR 镜头是否安装、固件是否支持 AUT 功能。若硬件不满足,AUT_Init()返回ERR01,但后续AUT_Search()仍会调用,固件因模块未就绪而报ERR01。
解决:严格检查AUT_Init()返回值。若失败,调用CSV_GetInstrumentName()确认仪器型号(TS30 支持 AUT,TS50 需选配),再调用CSV_GetDeviceConfig()检查 ATR 硬件状态。
4.2 现象:BAP_MeasDistanceAngle()测量值跳变极大(如 10m 突变到 1000m)
原因:未调用BAP_SetPrismType()设置正确棱镜常数,或BAP_SetEDMType()误设为EDM_TYPE_TRACKING(跟踪模式)。跟踪模式下 EDM 为连续发射,易受环境光干扰,且不校准大气折射,导致距离漂移。说明书 8.3.2 和 8.3.11 节明确要求“精测前必设棱镜类型”。
解决:在每次测量前,显式调用BAP_SetPrismType(PRISM_TYPE_MINI)(小棱镜)或PRISM_TYPE_STANDARD(标准棱镜),并确保BAP_SetEDMType(EDM_TYPE_PRECISION)。
4.3 现象:IMG_TakeTccImage()拍摄的图像全黑,或提示ERR08(图像模块忙)
原因:IMG_GetTccConfig()返回的曝光时间(Exposure Time)为 0,或IMG_SetTccConfig()未启用自动曝光(Auto Exposure)。TS30/TS50 的图像传感器需足够曝光时间,若固件配置为 0ms,图像必然全黑。说明书 14.4.1 和 14.4.2 节的TCC_CONFIG结构体中,exposure_time_ms字段必须 >0。
解决:调用IMG_GetTccConfig()获取当前配置,检查exposure_time_ms;若为 0,用IMG_SetTccConfig()设置合理值(如50ms),并开启auto_exposure = 1。
4.4 现象:FTR_Download()下载文件失败,返回ERR02(文件不存在)
原因:FTR_SetupDownload()的文件路径参数使用了 Windows 风格反斜杠\,如"C:\data\config.cfg"。GEOCOM 固件只识别正斜杠/,且路径必须是仪器内部存储的相对路径(如"/USER/CONFIG.CFG"),而非 PC 端绝对路径。说明书 13.3.4 节示例明确写为"/USER/TEST.DAT"。
解决:PC 端构造路径时统一用/,并确认文件已通过FTR_SetupList()上传到仪器/USER/目录下。
4.5 现象:程序运行数小时后,COM_NullProc()开始返回ERR07(会话无效),所有命令失效
原因:GEOCOM 会话有超时机制(默认 30 分钟无通信则断开)。长时间无操作后,固件主动释放会话资源。说明书 5.4.7 节COM_SetTimeout()可设置超时值,但更可靠的是定期心跳。
解决:在主循环中,每 20 分钟调用一次CSV_GetDateTime()(轻量级命令,不耗资源),维持会话活跃。这是说明书未明说,但固件实际执行的保活策略。
5. 二进制协议:GEOCOM 的“暗层”——RPC 包结构与固件交互的真相
当你深入到COM_OpenPort()的源码(说明书虽未提供,但可通过调试器反推),会发现 GEOCOM C 库的底层,是一套精简的二进制 RPC(Remote Procedure Call)协议。它比 ASCII 协议更高效,也更脆弱。理解它,是做高性能实时控制(如动态跟踪)的必经之路。
5.1 RPC 包结构:4 字节头 + N 字节负载,无文本解析开销
GEOCOM 的二进制模式(非 ASCII)使用固定包结构:
[4-byte Header][Payload]- Header(4 字节):
- Byte 0-1:命令 ID(如
0x0001=COM_NullProc,0x0108=AUT_Search); - Byte 2:参数长度(Payload 字节数);
- Byte 3:校验和(Header + Payload 所有字节异或)。
- Byte 0-1:命令 ID(如
- Payload(可变长):纯二进制参数,如
int32_t、float64_t,按小端序排列。
对比 ASCII 模式,二进制模式省去了字符串编码/解码、十进制转换、空格分隔等开销。一次AUT_Search()的 ASCII 帧约 12 字节("AU08<ETX><CHK>"),而二进制包仅 8 字节(0108 0000 00 XX)。在 9600 波特率下,传输效率提升 50%,这对需要高频轮询AUT_PS_SearchNext()的场景至关重要。
5.2 为什么说明书不公开二进制协议细节?
答案藏在说明书第 4.1.2 节 “RPC 描述的结构”:固件侧的 RPC 解析器与 PC 侧库强绑定。COM_OpenPort()初始化时,会读取固件的 RPC 版本号(通过COM_SwitchOnTPS()后的握手包),并动态加载对应命令 ID 映射表。不同固件版本(如 TS30 v2.1 vs v3.0),同一功能的命令 ID 可能不同。说明书只公开稳定的 ASCII 接口,是因为 ASCII 命令(如"AU08")是固件硬编码的,永不变更;而二进制 ID 是软件定义的,随固件升级而变。公开它,等于承诺接口稳定,这会锁死固件迭代。所以,GEOCOM.dll本身就是一个“协议翻译器”,它把 C 函数调用,翻译成当前固件能懂的二进制 RPC 包。
5.3 如何安全地“窥探”二进制层?—— 用COM_UseWindow()捕获原始包
说明书 5.4.10 节COM_UseWindow()常被忽略,但它是个神器。它允许你指定一个 Windows 窗口句柄,GEOCOM 库会将所有发送/接收的原始字节(包括二进制包)以WM_COPYDATA消息发给该窗口。你可以用简易 Win32 程序监听:
// 在窗口消息循环中 case WM_COPYDATA: COPYDATASTRUCT* cds = (COPYDATASTRUCT*)lParam; if (cds->dwData == 0x01) { // 发送包 printf("TX: "); for(int i=0; i<cds->cbData; i++) printf("%02X ", ((BYTE*)cds->lpData)[i]); printf("\n"); } break;这样,你就能看到AUT_Search()实际发出的二进制包0108 0000 00 09(ID=0108,长度=0,校验=09),以及固件返回的0108 0400 0000 0000 0000 0A(ID=0108,长度=4,返回值0x00000000= 成功)。这是调试二进制模式的唯一合法途径,比猜文档靠谱一万倍。
提示:
COM_UseWindow()必须在COM_OpenPort()之后、任何命令调用之前设置,否则无效。这是说明书 5.4.10 节的隐藏前提。
6. 设计取舍:为什么 GEOCOM 要用“笨办法”强制状态初始化,而不是自动管理?
这个问题困扰我很久。现代 API(如 USB HID、Bluetooth GATT)都支持自动连接、自动重连、自动状态同步。为什么 GEOCOM 要求开发者手动调用CSV_GetInstrumentName()、AUT_Init()、COM_SetTimeout()这一长串?为什么错误码要细分到ERR01~ERR09,而不是统一E_IO?翻遍说明书和固件行为,答案指向一个残酷的现实:TS30/TS50 的 MCU 资源极度紧张,没有空间跑一个健壮的状态管理守护进程。
6.1 资源约束下的设计真相
TS30/TS50 主控采用 ARM7TDMI(2002 年架构),主频 60MHz,RAM 仅 2MB,Flash 16MB。固件需同时运行:实时电机控制(望远镜伺服)、高速 EDM 信号处理(100MHz 采样)、ATR 图像识别(VGA 分辨率)、串口通信协议栈。在这种环境下,“自动管理”意味着:
- 需常驻后台线程轮询串口状态(占 CPU);
- 需维护会话超时定时器(占 RAM);
- 需实现命令重试逻辑(占 Flash);
- 需处理网络断连重连(TS30 无网口,但串口线松动等同于断连)。
GEOCOM 的选择是:把状态管理成本,100% 转嫁给 PC 端开发者。PC 端有充足 CPU、内存、磁盘,可以轻松实现重试、超时、日志、UI 反馈。固件只做最精简的事:收到合法帧,执行原子操作,返回结果。说明书第 3.4.4 节 “编程提示” 写道:“建议在关键操作前,调用COM_NullProc()确认通信”,这其实就是让你在 PC 端实现“健康检查”,而非固件自己做。
6.2 错误码细分:不是为了炫技,而是为快速定位硬件故障
ERR01(命令未识别)和ERR07(会话无效)看起来相似,但根因天壤之别:
ERR01:固件 ROM 中无此命令 ID → 可能是固件版本太老,或函数名拼错(如AUT_Searchh());ERR07:会话句柄失效 → 可能是串口线接触不良,或 PC 端崩溃未调用COM_ClosePort()。
如果合并为E_INVALID_CMD,你得花半小时查是固件问题还是线缆问题。细分错误码,是让开发者用最短路径(查说明书错误码表)直达根因。这在野外施工场景中价值巨大——工程师拿着平板电脑,没时间连电脑抓包,扫一眼错误码ERR09(温度过高),立刻知道要给仪器遮阳。
6.3 我的教训与习惯
从那以后,我每次写 GEOCOM 程序,都强制走一遍“初始化检查清单”:
COM_OpenPort()后,立即COM_NullProc(),确认物理链路;CSV_GetInstrumentName()后,打印仪器型号和固件版本,确认兼容性;CSV_GetDeviceConfig()后,检查atm_status(ATR 状态)和edm_status(EDM 状态);AUT_Init()和EDM_Init()后,分别调用AUT_ReadTol()和EDM_GetLaserpointer(),验证模块就绪;- 所有命令调用,都用
do { ... } while (ret == ERR05);循环等待异步完成(如AUT_Search)。
这套流程看似繁琐,但让我在三年内,零次因 GEOCOM 状态问题返工。希望帮到你。
本文还有配套的精品资源,点击获取