☰
巡检机器人梯控消防联动设计:基于边缘状态机的实战解析
2026/10/20 5:57:40 网站建设 项目流程

这两年我陆陆续续接触过好几个储能电站的智能巡检项目,其中让我印象最深的,不是导航算法,不是视觉识别,而是一套看起来特别“不起眼”的梯控系统。巡检机器人要跨楼层作业,就得自己坐电梯,而电梯又是第三方设备,坐不好轻则卡门、重则困梯,赶上消防联动,处理不当就是事故隐患。这篇我重点复盘一下我在某储能电站项目中,如何设计机器人梯控的消防联动逻辑,以及为什么最终把整套控制核心放在了“边缘状态机”上。

如果你正在做巡检机器人、楼宇配送机器人,或者任何需要和设备(电梯、门禁、闸机)打交道的边缘控制系统,这篇里的思路和踩坑经验应该能帮到你。

1. 这套系统到底要解决什么问题

先说清楚背景。储能电站的站房通常不止一层,比如地下有电池舱,一层是控制室,二层是辅助设备区。传统的人工巡检正在被轮式或挂轨式机器人取代,但机器人不能只在单层转悠,它需要自己坐电梯上下楼,到指定楼层执行红外测温、表计识别、气体探测这些任务。

看似很简单的需求,落到工程上就复杂了。机器人不是人,它对“电梯门开了没有”“轿厢是不是空的”“现在能不能进”这些感知完全依赖信号输入,而且电梯是第三方系统,通信协议、控制权限都要跟梯控厂商对。更麻烦的是储能电站属于消防重点单位,一旦触发火灾报警,电梯要强制归首、切断外部呼叫,所有设备必须让路。这时候机器人如果不做任何处理,轻则堵在电梯厅影响消防疏散,重则在轿厢里跟消防员抢电梯,直接造成联动事故。

1.1 巡检机器人用电梯,远没有想象中简单

先说机器人坐电梯这件事本身。日常流程大概是:机器人走到电梯厅,按上行或下行按钮,等电梯到达并开门,机器人确认门全开后进轿厢,按目标楼层,等电梯关门并运行,到达后等门开,最后出轿厢。

听起来行云流水,但每一步都涉及信号闭环。电梯是否到达、门是否开到位、轿厢是否有人、楼层是否匹配,这些信号从哪里来?一种是从梯控系统去读状态字,另一种是机器人自己用激光雷达或相机去“看”。最稳的做法是两者结合,但这块的坑很深。

比如电梯到位信号,很多梯控用干接点输出,继电器吸合表示“电梯已到”。但继电器触点存在弹跳,如果机器人直接把这一路信号接到IO口,大概率会出现“电梯明明没到,程序却认为到了”的误判。这时候就必须在软件上做去抖,甚至在硬件上加RC滤波或者光耦隔离。

还有一种情况是电梯门开的时间窗口。普通乘客对开门的感知是秒级的,但机器人从“识别到门开”到“完成进轿厢动作”可能需要3到5秒,如果电梯门只开了几秒就关闭,机器人就会被夹。所以我们做梯控时,必须通过协议向电梯申请“延长开门时间”,或者在机器人进轿厢的路径上增加安全传感器,检测到机器人进入后再让梯控关门。

1.2 消防联动为什么必须单独设计

消防联动在梯控系统里属于最高优先级事件,这点很多做机器人上层软件的同学会忽略。他们通常把消防信号当成一个普通的“告警”,直接在调度页面弹个提示,然后等人工处理。但在无人值守的储能电站,这套思路完全行不通。

电站的火灾报警控制器(FAS)一旦触发,通常会输出一路硬接点信号给电梯,电梯自动进入消防归首状态:无论当前在哪一层,都会就近停靠并返回指定层(通常是一层),然后开门等待。与此同时,普通的外呼、内呼全部失效,电梯进入消防员专用模式。

这时候如果机器人正在轿厢里,会发生什么?电梯会带着机器人一起归首,机器人如果没有在归首前及时退出,就可能被困在轿厢里,既无法继续任务,也耽误消防人员使用电梯。更严重的情况是机器人停在电梯厅门口,挡住消防通道,或者机器人仍按原计划执行“呼叫电梯”的动作,反复干扰梯控的消防逻辑。

所以消防联动必须单独设计成一条与业务解耦的高优先级链路,从信号接入到机器人响应,每一个环节都要有明确时序和降级策略。这也是我后来坚持把状态机放在边缘端而不是云端的原因之一。

1.3 状态机放在边缘而不是云端,真实原因

最开始我也考虑过“云端调度 + 机器人终端”这样的集中式架构,所有状态都在服务器上维护,机器人只是执行单元。但实际环境给了三个很现实的理由,让我最终选择了边缘状态机。

第一是断网容灾。储能电站现场有大量高压设备和金属舱体,无线信号环境很差,机器人跟调度中心的通信经常断断续续。如果梯控状态都放到云端,一断网机器人就失去判断能力,而电梯门不会等你重连。边缘状态机的好处是:即使断开网络,机器人本体依然能自主完成“叫梯、进梯、出梯、让梯”这些本地闭环动作。

第二是实时性。消防联动信号要求毫秒级响应,云端方案即使走局域网也有几毫秒到几十毫秒的抖动,还要经过消息队列、数据库、协议转换,响应链路过长。边缘端直接在机器人控制器里监听硬信号,从信号触发到状态迁移可以在几十毫秒内完成。

第三是可测试性。边缘状态机是确定性逻辑,每个状态、每个迁移条件都可以单独写单元测试。而云端的编排引擎虽然灵活,但出了问题不好复现,特别是电梯这种带机械运动的外设,一旦信号错乱,极难调试。状态机把“所有可能发生的情况”显式地列出来,测试覆盖就容易很多。

2. 整体架构与关键模块拆解

这个项目的整体架构可以分成四层:最上层是调度中心,负责任务编排和远程监控;往下是边缘控制器,也是机器人的“大脑”,跑导航、视觉、梯控状态机;再往下是设备接入层,包括梯控网关、消防信号采集模块、门禁系统;最底下是物理设备,也就是电梯、防火门、充电桩这些。

2.1 系统分层:机器人、梯控、消防、上层调度

先明确这四者的职责边界:

  • 调度中心:负责任务下发、机器人电量管理、跨楼层任务编排、异常告警。
  • 机器人边缘控制器:负责本体的运动控制、定位导航、视觉识别,以及跟梯控和消防的交互,核心就是边缘状态机。
  • 梯控系统:第三方电梯厂商的控制柜,管理电梯的呼叫、楼层选择、开关门、消防归首等动作。
  • 消防报警控制器(FAS):输出消防报警干接点信号,同时联动梯控进入消防状态。

这四者的关系不是简单的星型结构,而是一个有优先级的交织网络。消防信号要同时打到梯控和机器人,梯控的业务信号只面向机器人,调度中心则通过边缘控制器间接控制梯控。

我画过一个简化数据流:调度中心下发“去2楼巡检”任务给机器人,机器人进入梯控子状态机,向梯控发“外呼1层”,梯控返回“已响应”,机器人等电梯到位后进轿厢,再发“内呼2层”,电梯运行到2层后开门,机器人出轿厢,状态机回到空闲。在整个过程中,消防信号线一直处于监听状态,只要电平翻转,状态机立刻切到最高优先级分支。

2.2 梯控接口选型:干接点、RS485还是IP

梯控接口的选型是项目里第一件要定的事情,不同接口直接决定了你能读到什么信息、能控制到什么程度。

我整理了一张对比表:

接口方式信息丰富度实时性抗干扰能力典型场景缺点
干接点IO极低,只有通断毫秒级强,需去抖消防联动、紧急停梯无法区分呼叫类型
RS485/Modbus中,电梯层站、方向、门状态10ms级中,需屏蔽和隔离常规梯控指令总线冲突、布线要求高
IP/以太网高,所有状态字、诊断信息1ms~10ms弱,受网络影响信息集成要求高的场景需处理网络风暴

我们这个项目比较老派,梯控厂商给了两路接口:一路干接点专门给消防联动,一路RS485做业务控制。后来发现这个选择非常明智,因为消防联动用干接点是硬逻辑,不受通信协议故障影响,而业务控制用RS485虽然调试麻烦点,但数据可靠。

有一个细节值得说:RS485的A/B线一定要接终端电阻,现场遇到过通信偶发乱码的问题,查了半天发现是终端电阻没有接,长线反射把信号打乱了。还有梯控从站地址,如果现场有多台电梯并联,地址冲突会直接导致指令发给错误的电梯,这个在调试阶段必须逐一核对。

2.3 消防信号接入的三种方式与优先级处理

消防信号怎么接到机器人,我试过三种方式,各有优劣。

第一种,消防干接点直接进机器人IO模块。这是最简单的方式,信号链路最短,实时性最好。但问题是机器人IO模块通常电压等级不高,如果消防信号线路上有强干扰,容易造成误触发,而且机器人IO的隔离效果一般。

第二种,消防干接点先进梯控,再由梯控通过RS485把消防状态字传给机器人。这种方式布线最少,但有一个致命问题:如果梯控本身断电或者通信异常,消防状态就感知不到了。消防联动这种安全功能不能依赖第三方设备转发。

第三种,消防干接点通过中间继电器分成两路,一路给梯控,一路给机器人,同时再从FAS那边拉一路串口或Modbus信号做辅助确认。这种方式最稳,信号独立又可靠,是消防规范里比较推荐的做法。我们最后就用了这种方式,机器人端同时接了一路硬IO和一路串口状态,两路取与逻辑作为消防触发条件。

这里要特别强调优先级:硬IO信号 > 通信状态字 > 调度命令。为什么硬IO优先级最高?因为它的物理链路最短,不受任何中间设备故障影响。调度命令优先级最低,因为调度中心是业务系统,不能参与安全控制。

3. 边缘状态机设计与状态迁移

状态机是这套系统的灵魂。我把梯控和消防联动的所有逻辑都收敛成一个状态机,而不是散落在各个回调函数里。这么做最大的好处是:任何时刻你都能明确知道机器人在干什么,以及它下一步可能做什么。

3.1 状态划分逻辑:从叫梯到出梯的完整生命周期

我把梯控状态机划分为以下几个状态:

状态含义说明
IDLE空闲机器人没有梯控任务
CALLING叫梯中已发外呼,等待电梯响应
WAIT_DOOR_OPEN等待开门电梯到达,等门开到位
ENTERING进轿厢机器人正在进入轿厢
RIDING乘梯中电梯关门并运行,机器人轿厢内等待
EXITING出轿厢电梯到达目标层,机器人正在出去
FINISH任务完成出梯成功,可以做后续巡检任务
FIRE_HOLD消防让渡消防信号触发,机器人让出电梯
FAULT异常无法自动恢复的故障,需要人工介入

状态划分的粒度要适中。划分太细会导致迁移条件爆炸,划分太粗又不足以覆盖异常分支。我保留的这9个状态基本涵盖了所有业务路径,上方表格里没有写全的还有两个中间过渡态,比如WAIT_ENTRY_CONFIRM和WAIT_EXIT_SAFE,在实际编码里我合并到了ENTERING和EXITING内部。

3.2 状态迁移条件与超时、重试、异常分支

每个状态都要定义三样东西:进入条件、正常迁移条件、异常迁移条件。拿CALLING举例。

进入CALLING的时机是调度任务下发并且机器人已到达电梯厅,此时机器人向外呼信号。正常迁移是收到电梯到位信号后,进入WAIT_DOOR_OPEN。异常分支有两个:如果超过CALL_TIMEOUT(我设了15秒)还没收到到位信号,则重试一次外呼;如果重试两次后仍然失败,进入FAULT状态,上报调度中心。

超时参数的设计是整个状态机工程里最容易翻车的地方。设小了误报故障,设大了机器人会一直傻等。我总结的规律是:常规动作的超时时间 = 动作平均耗时 + 2倍标准差 + 安全余量,但要结合实际场地实测。

以电梯开门为例,空载电梯从门开始动作到完全打开,通常需要3到6秒。我设的DOOR_TIMEOUT是10秒,既能覆盖老电梯的慢动作,又不会让机器人在不正常的门状态上等太久。

3.3 状态机代码骨架示例

下面给一个简化版的状态机代码骨架,用Python描述,方便讲清楚思路。实际项目中我用的是C++实现,但状态迁移的逻辑是一样的。

from enum import Enum import time class LiftState(Enum): IDLE = 0 CALLING = 1 WAIT_DOOR_OPEN = 2 ENTERING = 3 RIDING = 4 EXITING = 5 FINISH = 6 FIRE_HOLD = 7 FAULT = 8 class EdgeLiftFsm: def __init__(self): self.state = LiftState.IDLE self.last_event = None self.fire_alarm = False def on_event(self, event, payload=None): # 消防信号优先级最高,任何状态都强制迁移 if event == "FIRE_ALARM_ACTIVE": self.fire_alarm = True self.state = LiftState.FIRE_HOLD self.on_fire_hold() return if self.state == LiftState.CALLING: if event == "ELEVATOR_ARRIVED": self.state = LiftState.WAIT_DOOR_OPEN self.start_door_timer(payload.get("timeout", 10)) elif event == "CALL_TIMEOUT": self.retry_call() if self.retry_count > 2: self.state = LiftState.FAULT elif self.state == LiftState.WAIT_DOOR_OPEN: if event == "DOOR_OPENED": self.state = LiftState.ENTERING self.start_enter_timer(5) elif event == "DOOR_TIMEOUT": self.state = LiftState.FAULT # 其他状态迁移逻辑类似,省略 def on_fire_hold(self): # 核心动作:取消当前梯控指令、让出电梯厅、移动到安全位置 self.lift_ctrl.cancel_all_commands() self.nav.move_to("safe_zone_1f") self.report_to_dispatch("FIRE_HOLD_ACTIVE")

关键设计点是:消防信号在事件入口处直接拦截,不需要经过当前状态的迁移判断。这保证了无论状态机处于哪个状态,都能第一时间进入FIRE_HOLD。有点像嵌入式系统里的中断优先级,你不能让一个运行中的业务流程挡住中断响应。

实际工程里我还加了一个看门狗,每500毫秒检查一次状态机是否仍在预期状态内。比如RIDING状态下,如果连续1分钟都没有收到任何电梯运行状态更新,看门狗会强行触发FAULT迁移,然后走异常恢复流程。

3.4 为什么用状态机而不是流程引擎

有人可能会问,既然有那么多流程编排的中间件,为什么要自己写状态机?

我的体会是,流程引擎擅长处理“正常情况下的长流程编排”,比如“先做A,再做B,再做C”。但梯控这种场景,核心矛盾在于异常情况太多、优先级抢占太频繁,流程引擎反而显得重。

状态机的优势是显式穷举。每一个状态都有清晰的定义,每一个迁移条件都能被测试覆盖。梯控系统最怕的就是“状态丢失”——不知道机器人现在到底在不在轿厢里。状态机天然解决了这个问题,因为状态是唯一且可查询的,任何时刻只要读取当前状态,就知道机器人处于什么处境。

另外状态机在故障复盘时特别好用。我们把每次状态迁移都打上了时间戳和事件源,事后可以完整回放几分钟前的迁移序列:机器人什么时候叫梯、什么时候收到到位信号、什么时候触发消防,一目了然。这个能力对消防事故调查尤其重要,因为安全事件一定要有据可查。

4. 消防联动时序设计与实操落地

消防联动不是简单地把消防信号接进来、在代码里写一个“如果报警就停”。真正的工程难点在于时序设计:报警发生后,机器人要在什么时间点做什么事,以及怎么判断是否安全。

4.1 消防触发后的标准时序

我用一个表格说明我们项目最终固化的联动时序:

时间点动作执行方信号状态
T+0ms火灾报警控制器触发FAS干接点闭合
T+50ms梯控收到消防信号,切消防归首模式电梯控制柜电梯开始归首
T+100ms机器人硬IO收到消防信号,状态机强制迁移边缘控制器FIRE_HOLD状态
T+300ms机器人取消所有梯控指令边缘控制器梯控收到取消指令
T+500ms机器人开始移动至安全区边缘控制器导航切换到避让模式
T+3s机器人到达电梯厅外安全区,上报调度边缘控制器调度收到状态
T+10s电梯归首到位,开门电梯控制柜消防模式完成
消防复位后机器人收到复位信号,状态机恢复IDLE边缘控制器等待调度下发新任务

这个时序最关键的窗口是T+100ms到T+500ms,在这400毫秒内,机器人要完成状态迁移、取消指令、启动避让三个动作。如果机器人正在轿厢内,还要多一个判断:电梯是否还在运行、能否立即打开门。

有一种情况特别考验设计:机器人正在乘梯,消防报警触发时电梯已经运行到两层之间的位置。此时不能盲目地“退出轿厢”,因为门可能不会开在楼层上。我们的做法是:机器人先保持静止,等待电梯自动行驶到最近楼层或归首层,然后检测到开门信号后再快速出轿厢,并移动到安全区。这个逻辑在状态机里就是FIRE_HOLD下的一个子状态分支。

4.2 联动参数配置与计算

联动参数的设定需要结合现场设备反应时间,不是拍脑袋定出来的。我们项目里几个关键参数都是实测后取的:

  • 消防信号去抖时间:200ms。硬IO信号在强电磁环境下会有毛刺,200ms的去抖可以有效过滤干扰,又不会影响响应速度。
  • 状态迁移看门狗:500ms。从FAS输出到机器人进入FIRE_HOLD状态,整个链路控制在500ms内,超过则触发硬复位。
  • 电梯归首等待超时:30s。从消防触发到电梯归首到位,正常情况下10s以内,我们给到30s作为冗余,超时后机器人不再等待电梯,直接走楼梯通道撤离到安全区。
  • 安全区就位确认:机器人到达安全区后,需要激光雷达定位确认并在调度端打卡,确认时间3s。

这些参数我都在实测环境里反复调过,调试时用信号发生器定时触发消防干接点,记录机器人收到信号到完成避让动作的时间线,然后对比预期时序表。

4.3 注入式测试:模拟消防报警的完整演练

消防联动功能的验证不能只靠“点一下测试按钮”,必须有完整的注入式测试。我们当时的做法是,在FAS和机器人IO之间串入一个可编程继电器,用脚本控制继电器按预设时序闭合和断开,模拟各种消防报警场景。

测试矩阵包括这么几类:

  • 机器人在IDLE状态时触发消防,应该直接进入FIRE_HOLD并保持。
  • 机器人在等梯状态时触发消防,应该取消外呼,退出电梯厅。
  • 机器人正在进轿厢时触发消防,应该停止进厢,向后退回安全区。
  • 机器人在轿厢内运行时触发消防,应该等待电梯停稳开门后迅速出厢。
  • 机器人在出梯过程中触发消防,应该加速出厢并让出电梯厅。
  • 消防信号在任意时刻突然断开(模拟信号线断裂),状态机应该进入FAULT并上报,而不是卡死。

这些测试全部通过后,还要做进阶测试:多台机器人同时乘梯,消防触发时所有机器人是否都能在时限内让出电梯?我们用两台机器人做过并发验证,发现如果不做全局互斥,两台机器人在电梯厅会互相堵路。后来在调度层增加了“消防优先互斥信号”,所有机器人收到该信号后不得进入电梯厅。

5. 常见问题与排查技巧实录

这部分我挑几个实际调试中最常见的坑来聊。每个坑背后都是一段调试血泪史,希望能帮你少走弯路。

5.1 信号抖动与电梯到位误判

现象:机器人叫梯后,状态机偶尔会提前进入“等待开门”状态,结果电梯还没到,机器人在电梯门前空等,然后超时报警。

排查过程:抓了梯控的RS485日志,发现电梯到位输出信号在电梯刚减速时就有一次短暂的脉动,导致机器人误以为到位。这是典型的继电器弹跳或者梯控状态字刷新时序问题。

解法:双通道校验。机器人不只看电梯到位信号,还要确认当前楼层和目标楼层一致,并且电梯处于静止状态,两者都满足才认为真正到位。另外在IO采样后面加200ms的去抖滤波。

5.2 消防状态下机器人“僵住”的问题

现象:消防报警已经触发,机器人状态机也进入了FIRE_HOLD,但机器人没有任何动作,一直停在原地,后续排查发现是运动控制模块还在等一个互斥锁,而这个锁被卡住了。

这个问题很有代表性:状态机迁移了,但业务模块没有同步释放资源。我后来在所有需要长时间持锁的环节都加了“消防信号强制释放”的监听,一旦消防信号生效,包括导航、梯控、机械臂在内的所有子模块都必须在100ms内释放资源。用一句话总结就是:状态机管逻辑,锁管资源,消防信号必须同时管两头。

5.3 多机器人抢梯与互斥

现象:有两台机器人同时要坐电梯,结果出现A机器人已进轿厢,B机器人还在疯狂外呼,导致电梯到上一层又下来,电梯门反复开关,最后两台机器人谁都没坐成。

原因:梯控系统本身只响应单台设备的外呼,如果调度层不做互斥,两台机器人会互相覆盖指令。

解法:在调度中心加了一个“电梯会话锁”,只有获得会话锁的机器人才能发梯控指令。会话锁有超时自动释放机制,防止机器人故障导致锁永占。同时每台机器人的梯控状态机里增加了“REQUEST_DENIED”事件,收到该事件后主动退避,等待下次调度。

5.4 接地干扰与通信不稳定

现象:RS485通信时好时坏,偶发错包,IO信号偶尔误触发。排查发现现场有一个变频柜和充电桩,动力线缆和信号线缆走在了同一个线槽里,而且屏蔽层两端都接地了,形成地环路。

解法:把模拟信号线和动力线分开布线,RS485屏蔽层改为单端接地,IO模块换成带光电隔离的型号,并在软件上对关键信号增加了CRC校验和重发机制。做完这三件事,通信误码率从千分之一级别降到了几乎为零。

5.5 问题排查速查表

现象可能原因排查方法解决方案
电梯到位误判继电器弹跳/状态位刷新时序抓RS485日志,比对楼层和状态双通道校验+去抖滤波
消防后机器人卡死互斥锁未释放查看线程堆栈,确认锁持有者信号强制释放机制
两台机器人抢梯调度无互斥检查调度日志,看外呼指令时间线会话锁+退避策略
RS485随机乱码接地环路/缺少终端电阻示波器看AB线波形屏蔽层单端接地+加终端电阻
消防状态无法退出复位信号未确认检查复位干接点是否正常双通道确认复位,超时强制恢复

6. 个人经验总结与后续演进

项目做完后复盘,我对“工业级梯控”有了几个比较深的体会,也沉淀了一些方法论。

6.1 部署中最容易踩的坑

先说一个我印象最深的教训:消防联动信号一定不要依赖电梯厂商的通信协议转发,一定要从FAS直接拉硬线到机器人。有一次我们测试时临时把机器人接在梯控的RS485口上读消防状态,梯控主板一重启,机器人直接丢失消防感知,差点出事。从那以后,我定了一条铁规矩:安全信号永远有独立物理链路,通信协议只能做辅助确认。

另一个坑是安全区的位置选择。我们最开始把电梯厅外的一片区域指定为“消防避让区”,结果发现消防报警时防火卷帘门会下降,把避让区隔断了。后来把安全区改到了楼梯间旁边的防火分区,并且用激光雷达做了动态边界检测,确保机器人永远不会被困在封闭区域。

调试上也要注意:千万不能只做“软件模拟测试”,一定要做信号注入式测试。我们的做法是把所有消防联动测试写成自动化脚本,在每次发布新版本后自动跑一遍,包括空闲、等梯、乘梯、出梯、多机并发五个场景,任何一个场景失败都不允许发布。

6.2 后续扩展方向

这套梯控系统的架构虽然是针对储能电站设计的,但稍微调整完全可以复用到其他场景,比如智慧园区配送机器人、医院物资运输机器人、变电站巡检机器人等。凡是机器人需要和电梯、门禁等设备联动的项目,都可以参考这套“边缘状态机+消防硬联动”的框架。

个人觉得后续有技术价值的方向有三个:第一,把轿厢内的状态感知从纯信号判断升级为UWB或视觉辅助,机器人可以更准确地判断轿厢是否拥挤、门是否被遮挡;第二,将梯控状态机与数字孪生平台对接,在虚拟环境里做全流程的仿真联调,进一步缩短现场调试时间;第三,消防联动逻辑向“主动上报”演进,机器人收到消防信号后直接向站端EMS发出辅助疏散建议,帮助运维人员更快掌握现场设备状态。

在实际项目里,这套状态机设计经过了大半年的运行验证,期间触发过三次消防演练联动,机器人的平均响应时间稳定在500ms以内,没有出现过一次卡死或者误动作。做机器人产品,最难的不是算法多炫酷,而是边缘侧的每个状态都可靠、可解释、可兜底。梯控和消防联动,就是检验这套能力的最好试金石。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询