在數(shù)字化轉(zhuǎn)型的浪潮中,積極響應(yīng)應(yīng)急管理部關(guān)于“工業(yè)互聯(lián)網(wǎng)+?;踩a(chǎn)”等指南的要求,打造工廠安全管理,守護(hù)生命防線、提高工廠效率,助力企業(yè)實(shí)現(xiàn)安全生產(chǎn)數(shù)字化升級(jí)至高重要。目前室內(nèi)高精度藍(lán)牙定位技術(shù)有不少,本文就以UWB和藍(lán)牙Beacon技術(shù)為例,展示其在工廠中的工作原理與應(yīng)用場(chǎng)景。
一、用UWB和藍(lán)牙Beacon方案實(shí)現(xiàn)室內(nèi)高精度藍(lán)牙定位的優(yōu)勢(shì)
結(jié)合UWB和藍(lán)牙Beacon的解決方案,有以下顯著優(yōu)勢(shì):
1. 互補(bǔ)性強(qiáng)
UWB適用于高精度的定位需求,且穿透性好、安全性高但需要單獨(dú)部署基礎(chǔ)設(shè)施,廣覆蓋成本高;而藍(lán)牙Beacon成本低,實(shí)現(xiàn)低成本廣覆蓋且傳輸數(shù)據(jù)功耗低。兩者結(jié)合,實(shí)現(xiàn)了低成本低功耗高精度定位(兩者皆有防爆和非防爆兩種版本)。
2. 靈活度高
UWB和藍(lán)牙Beacon模塊可以靈活部署在工廠的各個(gè)角落,根據(jù)實(shí)際需求調(diào)整覆蓋范圍和數(shù)據(jù)傳輸頻率,滿足多樣化的應(yīng)用場(chǎng)景。
3. 易于集成與維護(hù)
UWB和藍(lán)牙Beacon均具有較高的集成度和兼容性,可以方便地與其他智能設(shè)備或系統(tǒng)(如MES、ERP等)進(jìn)行對(duì)接,實(shí)現(xiàn)數(shù)據(jù)的共享和協(xié)同處理。
二、UWB和藍(lán)牙Beacon融合方案在室內(nèi)高精度定位中的配合戰(zhàn)
藍(lán)牙信標(biāo)和UWB都屬于信號(hào)發(fā)射設(shè)備,藍(lán)牙信標(biāo)助力信號(hào)廣覆蓋,完成粗定位。UWB實(shí)現(xiàn)精準(zhǔn)定位,車(chē)間等核心區(qū)密集部署,走廊等過(guò)渡區(qū)稀疏部署,兩者配合經(jīng)濟(jì)高效。
1.藍(lán)牙信標(biāo)定位原理
藍(lán)牙信標(biāo)廣播低功耗的藍(lán)牙信號(hào),定位器能感知區(qū)域只是“大概范圍”,比如廣部署在走廊區(qū)域、少部署在車(chē)間的核心區(qū)域,判斷初始位置的區(qū)域是A還是B,減少UWB的解算消耗。
2.UWB定位原理
UWB發(fā)送超窄脈沖信號(hào),定位器能夠測(cè)算它信號(hào)的距離(至少兩個(gè)UWB基站通過(guò)三角定位計(jì)算坐標(biāo)),實(shí)現(xiàn)精準(zhǔn)定位,需要多部署在車(chē)間等的核心區(qū)域,走廊等過(guò)渡區(qū)域少部署,完成人員、設(shè)備從走廊進(jìn)入車(chē)間的無(wú)縫切換,避免定位中斷。
三、UWB和藍(lán)牙Beacon融合方案在室內(nèi)高精度定位中的實(shí)現(xiàn)
1.部署發(fā)射端并發(fā)出信號(hào)
把低功耗藍(lán)牙信標(biāo)安裝在需要定位的區(qū)域內(nèi),采用粘貼、懸掛等安裝方式,部署簡(jiǎn)單高效,藍(lán)牙信標(biāo)單向廣播自身ID和BLE信號(hào);再部署好UWB基站,基站多采用雙向通信。
2. 定位器采集并處理信號(hào)
給需要定位的人員、物資分配融合定位器。定位器被動(dòng)接收藍(lán)牙信標(biāo)發(fā)出的信號(hào)強(qiáng)度(RSSI),對(duì)于UWB基站,定位器先向它發(fā)送“測(cè)距請(qǐng)求”,基站響應(yīng)后,兩者通過(guò)計(jì)算信號(hào)的返回距離(TOF)確定距離,最后定位器對(duì)采集到的數(shù)據(jù)進(jìn)行匯總,并完成基礎(chǔ)計(jì)算——將藍(lán)牙信標(biāo)發(fā)出的信號(hào)強(qiáng)度(RSSI)值轉(zhuǎn)化為距離估算值,對(duì)UWB計(jì)算到達(dá)距離(TOF)/到達(dá)時(shí)間差(TDOA)。
融合定位器信號(hào)采集與處理代碼實(shí)現(xiàn)
import time
import random
from dataclasses import dataclass, field
from typing import List, Optional, Tuple
import math
# -------------------------- 數(shù)據(jù)結(jié)構(gòu)定義 --------------------------
@dataclass
class BluetoothBeaconData:
"""藍(lán)牙信標(biāo)采集數(shù)據(jù)"""
beacon_id: str # 信標(biāo)唯一標(biāo)識(shí)
rssi: int # 接收信號(hào)強(qiáng)度(dBm)
timestamp: float = field(default_factory=time.time) # 采集時(shí)間戳
estimated_distance: Optional[float] = None # 估算距離(m)
@dataclass
class UWBBaseStationData:
"""UWB基站采集數(shù)據(jù)"""
base_station_id: str # 基站唯一標(biāo)識(shí)
tof: Optional[float] = None # 飛行時(shí)間(s)
tdoa: Optional[float] = None # 到達(dá)時(shí)間差(s)
distance: Optional[float] = None # 計(jì)算距離(m)
request_timestamp: Optional[float] = None # 測(cè)距請(qǐng)求時(shí)間
response_timestamp: Optional[float] = None # 基站響應(yīng)時(shí)間
@dataclass
class FusionLocatorResult:
"""定位器最終處理結(jié)果"""
locator_id: str # 定位器ID
bluetooth_data_list: List[BluetoothBeaconData] = field(default_factory=list) # 藍(lán)牙數(shù)據(jù)列表
uwb_data_list: List[UWBBaseStationData] = field(default_factory=list) # UWB數(shù)據(jù)列表
process_timestamp: float = field(default_factory=time.time) # 處理完成時(shí)間
# -------------------------- 常量定義 --------------------------
SPEED_OF_LIGHT = 299792458.0 # 光速(m/s),UWB信號(hào)傳播速度近似光速
BLUETOOTH_PARAMS = {
"reference_rssi": -55, # 1米處參考RSSI值(需根據(jù)硬件校準(zhǔn))
"path_loss_exponent": 2.4 # 路徑損耗指數(shù)(室內(nèi)環(huán)境通常2.0-4.0)
}
# -------------------------- 融合定位器核心類(lèi) --------------------------
class FusionLocator:
def __init__(self, locator_id: str):
self.locator_id = locator_id
self.bluetooth_beacon_ids = set() # 可檢測(cè)的藍(lán)牙信標(biāo)ID集合
self.uwb_base_station_ids = set() # 可通信的UWB基站ID集合
def add_bluetooth_beacon(self, beacon_id: str) - > None:
"""添加可檢測(cè)的藍(lán)牙信標(biāo)"""
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)
# -------------------------- 藍(lán)牙信號(hào)處理 --------------------------
def receive_bluetooth_rssi(self) - > List[BluetoothBeaconData]:
"""
模擬被動(dòng)接收藍(lán)牙信標(biāo)RSSI信號(hào)
實(shí)際場(chǎng)景中需替換為硬件的藍(lán)牙信號(hào)采集接口
"""
bluetooth_data_list = []
for beacon_id in self.bluetooth_beacon_ids:
# 模擬RSSI值(實(shí)際從藍(lán)牙模塊讀?。?/span>
rssi = random.randint(-85, -40) # 典型室內(nèi)RSSI范圍
bluetooth_data = BluetoothBeaconData(
beacon_id=beacon_id,
rssi=rssi
)
# 實(shí)時(shí)計(jì)算距離估算值
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:
"""
根據(jù)RSSI計(jì)算距離(對(duì)數(shù)路徑損耗模型)
公式:d = 10^((RSSI_reference - RSSI_measured) / (10 * n))
其中:d-距離(m),n-路徑損耗指數(shù),RSSI_reference-1米處參考信號(hào)強(qiáng)度
"""
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距離計(jì)算失?。簕e}")
bluetooth_data.estimated_distance = None
# -------------------------- UWB信號(hào)處理 --------------------------
def send_uwb_ranging_request(self, base_station_id: str) - > Tuple[bool, float]:
"""
向UWB基站發(fā)送測(cè)距請(qǐng)求
實(shí)際場(chǎng)景中需替換為UWB模塊的通信接口(如SPI/UART)
"""
try:
# 模擬請(qǐng)求發(fā)送(實(shí)際硬件發(fā)送指令)
request_timestamp = time.time()
print(f"[{request_timestamp:.3f}] 向UWB基站 {base_station_id} 發(fā)送測(cè)距請(qǐng)求")
# 模擬基站響應(yīng)延遲(實(shí)際等待硬件響應(yīng))
time.sleep(random.uniform(0.001, 0.005)) # UWB響應(yīng)延遲通常為毫秒級(jí)
return True, request_timestamp
except Exception as e:
print(f"UWB測(cè)距請(qǐng)求發(fā)送失?。簕e}")
return False, 0.0
def receive_uwb_response(self, base_station_id: str, request_timestamp: float) - > Optional[UWBBaseStationData]:
"""
接收UWB基站響應(yīng)并計(jì)算TOF/距離
"""
try:
response_timestamp = time.time()
# 模擬UWB基站返回的飛行時(shí)間相關(guān)數(shù)據(jù)(實(shí)際從硬件讀?。?/span>
# TOF = (響應(yīng)時(shí)間 - 請(qǐng)求時(shí)間) / 2(信號(hào)往返)
tof = (response_timestamp - request_timestamp) / 2
# 計(jì)算距離(距離 = 光速 * TOF)
distance = SPEED_OF_LIGHT * tof
uwb_data = UWBBaseStationData(
base_station_id=base_station_id,
tof=round(tof, 9), # 保留9位小數(shù)(納秒級(jí)精度)
distance=round(distance, 3),
request_timestamp=request_timestamp,
response_timestamp=response_timestamp
)
return uwb_data
except Exception as e:
print(f"UWB響應(yīng)接收失?。簕e}")
return None
def calculate_uwb_tdoa(self, uwb_data_list: List[UWBBaseStationData]) - > None:
"""
計(jì)算UWB到達(dá)時(shí)間差(TDOA)
基于多個(gè)基站的TOF,計(jì)算相對(duì)于第一個(gè)基站的時(shí)間差
"""
if len(uwb_data_list) < 2:
print("計(jì)算TDOA需要至少2個(gè)UWB基站數(shù)據(jù)")
return
# 以第一個(gè)基站為參考
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測(cè)距流程:請(qǐng)求- >響應(yīng)- >TOF計(jì)算- >TDOA計(jì)算
"""
uwb_data_list = []
for base_station_id in self.uwb_base_station_ids:
# 發(fā)送測(cè)距請(qǐng)求
success, request_ts = self.send_uwb_ranging_request(base_station_id)
if not success:
continue
# 接收響應(yīng)并計(jì)算TOF/距離
uwb_data = self.receive_uwb_response(base_station_id, request_ts)
if uwb_data:
uwb_data_list.append(uwb_data)
# 計(jì)算TDOA(多基站場(chǎng)景)
self.calculate_uwb_tdoa(uwb_data_list)
return uwb_data_list
# -------------------------- 數(shù)據(jù)匯總與輸出 --------------------------
def collect_and_process(self) - > FusionLocatorResult:
"""
核心流程:采集藍(lán)牙/UWB數(shù)據(jù) - > 處理計(jì)算 - > 匯總結(jié)果
"""
print(f"n===== 定位器 {self.locator_id} 開(kāi)始數(shù)據(jù)采集與處理 =====")
# 1. 采集并處理藍(lán)牙數(shù)據(jù)
bluetooth_data = self.receive_bluetooth_rssi()
# 2. 采集并處理UWB數(shù)據(jù)
uwb_data = self.process_uwb_ranging()
# 3. 匯總結(jié)果
result = FusionLocatorResult(
locator_id=self.locator_id,
bluetooth_data_list=bluetooth_data,
uwb_data_list=uwb_data
)
# 打印處理結(jié)果(實(shí)際場(chǎng)景可發(fā)送至服務(wù)器或本地存儲(chǔ))
self.print_result(result)
return result
def print_result(self, result: FusionLocatorResult) - > None:
"""打印處理結(jié)果(調(diào)試/日志用)"""
print(f"n【處理完成時(shí)間】: {result.process_timestamp:.3f}")
print("n【藍(lán)牙信標(biāo)數(shù)據(jù)】:")
for bt in result.bluetooth_data_list:
print(f" 信標(biāo)ID: {bt.beacon_id:4s} | RSSI: {bt.rssi:4d} dBm | 估算距離: {bt.estimated_distance:.3f} m")
print("n【UWB基站數(shù)據(jù)】:")
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)
# -------------------------- 測(cè)試代碼 --------------------------
if __name__ == "__main__":
# 1. 初始化融合定位器
locator = FusionLocator(locator_id="LOC-001")
# 2. 配置可檢測(cè)的藍(lán)牙信標(biāo)和UWB基站
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")
# 3. 執(zhí)行數(shù)據(jù)采集與處理(實(shí)際場(chǎng)景可設(shè)置定時(shí)循環(huán))
for _ in range(2): # 模擬2次采集周期
locator.collect_and_process()
time.sleep(1) # 采集周期間隔(可根據(jù)需求調(diào)整)

3. 服務(wù)器解算位置并實(shí)現(xiàn)
定位器將初步處理好的數(shù)據(jù)送到引擎服務(wù)器,自研算法對(duì)兩類(lèi)數(shù)據(jù)進(jìn)行解算并結(jié)合卡爾曼濾波降低噪聲對(duì)信號(hào)干擾,最終精準(zhǔn)算出人員/物資的實(shí)時(shí)位置,存儲(chǔ)數(shù)據(jù)到云端/本地,進(jìn)行處理后實(shí)現(xiàn)工廠的可視化管理,并在系統(tǒng)后臺(tái)呈現(xiàn)。
本篇文章深入剖析了UWB和藍(lán)牙Beacon融合方案優(yōu)勢(shì)和在工廠中的工作原理,該方案不僅降低了成本,還實(shí)現(xiàn)了高精度、低功耗的人員/資產(chǎn)定位管理。
希望本篇文章對(duì)大家有所幫助,由于篇幅原因,應(yīng)用場(chǎng)景會(huì)放在下篇,下篇將對(duì)室內(nèi)高精度藍(lán)牙定位系統(tǒng)的系統(tǒng)亮點(diǎn)和系統(tǒng)功能進(jìn)行分享,感興趣的朋友可以關(guān)注一下~~
審核編輯 黃宇
-
藍(lán)牙
+關(guān)注
關(guān)注
117文章
6185瀏覽量
177061 -
定位系統(tǒng)
+關(guān)注
關(guān)注
10文章
638瀏覽量
37426 -
UWB
+關(guān)注
關(guān)注
32文章
1223瀏覽量
64407 -
Beacon
+關(guān)注
關(guān)注
0文章
37瀏覽量
10674
發(fā)布評(píng)論請(qǐng)先 登錄

基于UWB和藍(lán)牙Beacon:室內(nèi)高精度藍(lán)牙定位系統(tǒng)在工廠中的工作原理與應(yīng)用場(chǎng)景(一)
評(píng)論