在数字化转型的浪潮中,积极响应应急管理部关于“工业互联网+危化安全生产”等指南的要求,打造工厂安全管理,守护生命防线、提高工厂效率,助力企业实现安全生产数字化升级至高重要。目前室内高精度蓝牙定位技术有不少,本文就以UWB和蓝牙Beacon技术为例,展示其在工厂中的工作原理与应用场景。
一、用UWB和蓝牙Beacon方案实现室内高精度蓝牙定位的优势
结合UWB和蓝牙Beacon的解决方案,有以下显著优势:
1. 互补性强
UWB适用于高精度的定位需求,且穿透性好、安全性高但需要单独部署基础设施,广覆盖成本高;而蓝牙Beacon成本低,实现低成本广覆盖且传输数据功耗低。两者结合,实现了低成本低功耗高精度定位(两者皆有防爆和非防爆两种版本)。
2. 灵活度高
UWB和蓝牙Beacon模块可以灵活部署在工厂的各个角落,根据实际需求调整覆盖范围和数据传输频率,满足多样化的应用场景。
3. 易于集成与维护
UWB和蓝牙Beacon均具有较高的集成度和兼容性,可以方便地与其他智能设备或系统(如MES、ERP等)进行对接,实现数据的共享和协同处理。
二、UWB和蓝牙Beacon融合方案在室内高精度定位中的配合战
蓝牙信标和UWB都属于信号发射设备,蓝牙信标助力信号广覆盖,完成粗定位。UWB实现精准定位,车间等核心区密集部署,走廊等过渡区稀疏部署,两者配合经济高效。
1.蓝牙信标定位原理
蓝牙信标广播低功耗的蓝牙信号,定位器能感知区域只是“大概范围”,比如广部署在走廊区域、少部署在车间的核心区域,判断初始位置的区域是A还是B,减少UWB的解算消耗。
蓝牙信标和防爆型蓝牙信标
2.UWB定位原理
UWB发送超窄脉冲信号,定位器能够测算它信号的距离(至少两个UWB基站通过三角定位计算坐标),实现精准定位,需要多部署在车间等的核心区域,走廊等过渡区域少部署,完成人员、设备从走廊进入车间的无缝切换,避免定位中断。
三、UWB和蓝牙Beacon融合方案在室内高精度定位中的实现
1.部署发射端并发出信号
把低功耗蓝牙信标安装在需要定位的区域内,采用粘贴、悬挂等安装方式,部署简单高效,蓝牙信标单向广播自身ID和BLE信号;再部署好UWB基站,基站多采用双向通信。
2. 定位器采集并处理信号
给需要定位的人员、物资分配融合定位器。定位器被动接收蓝牙信标发出的信号强度(RSSI),对于UWB基站,定位器先向它发送“测距请求”,基站响应后,两者通过计算信号的返回距离(TOF)确定距离,最后定位器对采集到的数据进行汇总,并完成基础计算——将蓝牙信标发出的信号强度(RSSI)值转化为距离估算值,对UWB计算到达距离(TOF)/到达时间差(TDOA)。
融合定位器信号采集与处理代码实现 import time import random from dataclasses import dataclass, field from typing import List, Optional, Tuple import math @dataclass class BluetoothBeaconData: """蓝牙信标采集数据""" beacon_id: str # 信标唯一标识 rssi: int # 接收信号强度(dBm) timestamp: float = field(default_factory=time.time) # 采集时间戳 estimated_distance: Optional[float] = None # 估算距离(m) @dataclass class UWBBaseStationData: """UWB基站采集数据""" base_station_id: str # 基站唯一标识 tof: Optional[float] = None # 飞行时间(s) tdoa: Optional[float] = None # 到达时间差(s) distance: Optional[float] = None # 计算距离(m) request_timestamp: Optional[float] = None # 测距请求时间 response_timestamp: Optional[float] = None # 基站响应时间 @dataclass class FusionLocatorResult: """定位器最终处理结果""" locator_id: str # 定位器ID bluetooth_data_list: List[BluetoothBeaconData] = field(default_factory=list) # 蓝牙数据列表 uwb_data_list: List[UWBBaseStationData] = field(default_factory=list) # UWB数据列表 process_timestamp: float = field(default_factory=time.time) # 处理完成时间 SPEED_OF_LIGHT = 299792458.0 # 光速(m/s),UWB信号传播速度近似光速 BLUETOOTH_PARAMS = { "reference_rssi": -55, # 1米处参考RSSI值(需根据硬件校准) "path_loss_exponent": 2.4 # 路径损耗指数(室内环境通常2.0-4.0) } class FusionLocator: def __init__(self, locator_id: str): self.locator_id = locator_id self.bluetooth_beacon_ids = set() # 可检测的蓝牙信标ID集合 self.uwb_base_station_ids = set() # 可通信的UWB基站ID集合 def add_bluetooth_beacon(self, beacon_id: str) -> None: """添加可检测的蓝牙信标""" self.bluetooth_beacon_ids.add(beacon_id) def add_uwb_base_station(self, base_station_id: str) -> None: """添加可通信的UWB基站""" self.uwb_base_station_ids.add(base_station_id) def receive_bluetooth_rssi(self) -> List[BluetoothBeaconData]: """ 模拟被动接收蓝牙信标RSSI信号 实际场景中需替换为硬件的蓝牙信号采集接口 """ bluetooth_data_list = [] for beacon_id in self.bluetooth_beacon_ids: rssi = random.randint(-85, -40) # 典型室内RSSI范围 bluetooth_data = BluetoothBeaconData( beacon_id=beacon_id, rssi=rssi ) self.calculate_rssi_distance(bluetooth_data) bluetooth_data_list.append(bluetooth_data) return bluetooth_data_list def calculate_rssi_distance(self, bluetooth_data: BluetoothBeaconData) -> None: """ 根据RSSI计算距离(对数路径损耗模型) 公式:d = 10^((RSSI_reference - RSSI_measured) / (10 * n)) 其中:d-距离(m),n-路径损耗指数,RSSI_reference-1米处参考信号强度 """ ref_rssi = BLUETOOTH_PARAMS["reference_rssi"] n = BLUETOOTH_PARAMS["path_loss_exponent"] try: distance = math.pow(10, (ref_rssi - bluetooth_data.rssi) / (10 * n)) bluetooth_data.estimated_distance = round(distance, 3) except Exception as e: print(f"RSSI距离计算失败:{e}") bluetooth_data.estimated_distance = None def send_uwb_ranging_request(self, base_station_id: str) -> Tuple[bool, float]: """ 向UWB基站发送测距请求 实际场景中需替换为UWB模块的通信接口(如SPI/UART) """ try: request_timestamp = time.time() print(f"[{request_timestamp:.3f}] 向UWB基站 {base_station_id} 发送测距请求") time.sleep(random.uniform(0.001, 0.005)) # UWB响应延迟通常为毫秒级 return True, request_timestamp except Exception as e: print(f"UWB测距请求发送失败:{e}") return False, 0.0 def receive_uwb_response(self, base_station_id: str, request_timestamp: float) -> Optional[UWBBaseStationData]: """ 接收UWB基站响应并计算TOF/距离 """ try: response_timestamp = time.time() tof = (response_timestamp - request_timestamp) / 2 distance = SPEED_OF_LIGHT * tof uwb_data = UWBBaseStationData( base_station_id=base_station_id, tof=round(tof, 9), # 保留9位小数(纳秒级精度) distance=round(distance, 3), request_timestamp=request_timestamp, response_timestamp=response_timestamp ) return uwb_data except Exception as e: print(f"UWB响应接收失败:{e}") return None def calculate_uwb_tdoa(self, uwb_data_list: List[UWBBaseStationData]) -> None: """ 计算UWB到达时间差(TDOA) 基于多个基站的TOF,计算相对于第一个基站的时间差 """ if len(uwb_data_list) < 2: print("计算TDOA需要至少2个UWB基站数据") return reference_tof = uwb_data_list[0].tof for uwb_data in uwb_data_list[1:]: if uwb_data.tof is not None: uwb_data.tdoa = round(uwb_data.tof - reference_tof, 9) else: uwb_data.tdoa = None def process_uwb_ranging(self) -> List[UWBBaseStationData]: """ 完整UWB测距流程:请求->响应->TOF计算->TDOA计算 """ uwb_data_list = [] for base_station_id in self.uwb_base_station_ids: success, request_ts = self.send_uwb_ranging_request(base_station_id) if not success: continue uwb_data = self.receive_uwb_response(base_station_id, request_ts) if uwb_data: uwb_data_list.append(uwb_data) self.calculate_uwb_tdoa(uwb_data_list) return uwb_data_list def collect_and_process(self) -> FusionLocatorResult: """ 核心流程:采集蓝牙/UWB数据 -> 处理计算 -> 汇总结果 """ print(f"\n===== 定位器 {self.locator_id} 开始数据采集与处理 =====") bluetooth_data = self.receive_bluetooth_rssi() uwb_data = self.process_uwb_ranging() result = FusionLocatorResult( locator_id=self.locator_id, bluetooth_data_list=bluetooth_data, uwb_data_list=uwb_data ) self.print_result(result) return result def print_result(self, result: FusionLocatorResult) -> None: """打印处理结果(调试/日志用)""" print(f"\n【处理完成时间】: {result.process_timestamp:.3f}") print("\n【蓝牙信标数据】:") for bt in result.bluetooth_data_list: print(f" 信标ID: {bt.beacon_id:4s} | RSSI: {bt.rssi:4d} dBm | 估算距离: {bt.estimated_distance:.3f} m") print("\n【UWB基站数据】:") for uwb in result.uwb_data_list: print(f" 基站ID: {uwb.base_station_id:4s} | TOF: {uwb.tof:.9f} s | " f"距离: {uwb.distance:.3f} m | TDOA: {uwb.tdoa if uwb.tdoa else 'N/A'} s") print("=" * 60) if __name__ == "__main__": locator = FusionLocator(locator_id="LOC-001") locator.add_bluetooth_beacon("BEACON-01") locator.add_bluetooth_beacon("BEACON-02") locator.add_bluetooth_beacon("BEACON-03") locator.add_uwb_base_station("UWB-001") locator.add_uwb_base_station("UWB-002") locator.add_uwb_base_station("UWB-003") for _ in range(2): # 模拟2次采集周期 locator.collect_and_process() time.sleep(1) # 采集周期间隔(可根据需求调整)
3. 服务器解算位置并实现
定位器将初步处理好的数据送到引擎服务器,自研算法对两类数据进行解算并结合卡尔曼滤波降低噪声对信号干扰,最终精准算出人员/物资的实时位置,存储数据到云端/本地,进行处理后实现工厂的可视化管理,并在系统后台呈现。
系统框架
本篇文章深入剖析了UWB和蓝牙Beacon融合方案优势和在工厂中的工作原理,该方案不仅降低了成本,还实现了高精度、低功耗的人员/资产定位管理。
希望本篇文章对大家有所帮助,由于篇幅原因,应用场景会放在下篇,下篇将对室内高精度蓝牙定位系统的系统亮点和系统功能进行分享,感兴趣的朋友可以关注一下~~