基于TWR私有协议DW1000双天线DS-TWR+PDoA单基站二维定位实现方案
本文在原有STAR_SE平台+TWR私有UWB协议+DS-TWR双向测距工程基础上,升级实现DW1000单芯片双天线定位。区别于传统多基站TWR交会定位,本方案依托DS-TWR测距+PDoA相位差测角融合算法,实现单基站二维(X,Y)坐标定位,完全适配现有协议架构与硬件平台,解决多基站部署繁琐、成本高的问题。
一、核心原理澄清(工程关键)
1.1 DW1000双天线核心误区纠正
DW1000芯片内部仅有一套射频收发内核,无双路独立收发通道,双天线并非双收发链路,核心工作机制为单射频、时分切换、单路接收测相位差:
硬件由单DW1000芯片+外部射频模拟开关(PE4259)+双平行天线组成
通过MCU高速切换天线通路,分时接收同一标签UWB信号
分别采集两路天线的信号接收相位,计算相位差PDoA,反推信号入射角度
搭配DS-TWR测算的精准直线距离,极坐标转直角坐标,完成二维定位
核心组合:TWR测距离R + PDoA测角度θ = 单基站二维定位。
1.2 双天线TWR+PDoA定位数学原理
1.2.1 DS-TWR测距公式(沿用原有工程)
基于四时间戳计算信号飞行时间与直线距离:
tTOF=(t2−t1)+(t4−t3)2t_{TOF} = \frac{(t_2-t_1)+(t_4-t_3)}{2}tTOF=2(t2−t1)+(t4−t3)
R=tTOF×cR = t_{TOF} \times cR=tTOF×c
式中:t1t_1t1标签发POLL时间戳、t2t_2t2基站收POLL时间戳、t3t_3t3基站发ACK时间戳、t4t_4t4标签收ACK时间戳,ccc为光速。
1.2.2 PDoA相位差测角公式
双天线固定间距ddd(工程常用10cm),UWB信号波长λ\lambdaλ,两路天线接收相位差Δφ\Delta\varphiΔφ,入射角度计算公式:
θ=arcsin(Δφ⋅λ2π⋅d)\theta = \arcsin\left(\frac{\Delta\varphi \cdot \lambda}{2\pi \cdot d}\right)θ=arcsin(2π⋅dΔφ⋅λ)
1.2.3 极坐标转直角坐标(最终定位坐标)
X=R⋅cosθ,Y=R⋅sinθX = R \cdot \cos\theta,\quad Y = R \cdot \sin\thetaX=R⋅cosθ,Y=R⋅sinθ
1.3 双天线定位与传统多基站TWR定位对比
| 定位方案 | 硬件需求 | 核心原理 | 部署难度 | 适用场景 |
|---|---|---|---|---|
| 多基站纯TWR定位 | ≥3个单天线基站 | 三边距离交会解方程 | 高,需多点校准组网 | 大范围固定场景 |
| 单基站双天线TWR+PDoA | 1个双天线基站+单标签 | 距离+角度融合解算坐标 | 极低,单点部署即可 | 室内小范围、移动定位 |
二、整体系统架构(兼容原有TWR私有协议工程)
2.1 设备角色分工
Initiator(标签Tag):保持原有DS-TWR逻辑,主动发起POLL测距,无硬件修改,完全兼容原有代码
Responder(双天线基站Anchor):新增天线切换、相位采集、角度解算、坐标计算功能,保留原有TWR私有协议加解密、帧交互逻辑
2.2 新增功能模块
天线切换硬件驱动(射频开关控制)
DW1000相位寄存器读取接口
PDoA角度解算算法
极坐标转直角坐标定位算法
坐标滤波防抖优化
三、硬件适配设计
3.1 硬件架构
STAR_SE主控 + DW1000 + PE4259射频开关 + 双平行天线(间距100mm标准配置)
3.2 引脚定义(新增天线切换引脚)
// 双天线射频开关控制引脚(STAR_SE平台) #define RF_SW_PIN GPIO_PIN_3 #define RF_SW_PORT GPIOA3.3 天线切换时序
基站空闲状态:默认切换至天线1
接收标签POLL帧:先切换天线1接收,读取相位P1
快速切换天线2,二次接收同帧信号,读取相位P2
计算相位差,解算角度,结合TWR距离输出坐标
四、完整代码适配升级
4.1 底层驱动新增:天线切换驱动(uwb_dw1000_drv.h)
在原有头文件新增天线控制与相位读取接口
// 新增:双天线射频切换控制 void UWB_Antenna_Switch(uint8_t ant_id); // ant_id:1/2 切换对应天线 // 新增:读取UWB接收相位值 float UWB_Get_Rx_Phase(void);4.2 底层驱动实现(uwb_dw1000_drv.c)
/** * @brief 双天线切换控制 * @param ant_id:1-天线1 2-天线2 * @retval 无 */ void UWB_Antenna_Switch(uint8_t ant_id) { GPIO_InitTypeDef gpio_init = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); gpio_init.Pin = RF_SW_PIN; gpio_init.Mode = GPIO_MODE_OUTPUT_PP; gpio_init.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(RF_SW_PORT, &gpio_init); // PE4259开关电平逻辑 if(ant_id == 1) HAL_GPIO_WritePin(RF_SW_PORT, RF_SW_PIN, GPIO_PIN_RESET); else HAL_GPIO_WritePin(RF_SW_PORT, RF_SW_PIN, GPIO_PIN_SET); HAL_Delay(1); // 射频切换稳定延时 } /** * @brief 读取DW1000接收信号相位值 * @retval 相位值(弧度) */ float UWB_Get_Rx_Phase(void) { uint8_t phase_buf[2] = {0}; // 读取DW1000相位寄存器 DW1000_Recv(phase_buf, 2, 10); uint16_t phase_raw = (phase_buf[1] << 8) | phase_buf[0]; // 寄存器值转弧度(DW1000标准换算) float phase = (float)phase_raw / 4096.0f * 2 * 3.1415926f; return phase; }4.3 业务层升级:新增定位结构体(uwb_twr_app.h)
// 双天线PDoA定位参数 typedef struct{ float phase1; // 天线1接收相位 float phase2; // 天线2接收相位 float phase_diff; // 相位差 float angle_deg; // 入射角度(度) float pos_x; // 定位X坐标(m) float pos_y; // 定位Y坐标(m) }UWB_PDoA_PosTypeDef; // 在原有UWB_TWR_HandleTypeDef句柄中新增定位结构体 UWB_PDoA_PosTypeDef pdoa_pos;4.4 核心算法实现:PDoA解算+坐标转换
// 双天线硬件参数(固定校准值) #define ANT_DISTANCE 0.1f // 天线间距0.1m #define UWB_WAVE_LEN 0.175f // UWB信道2波长 /** * @brief PDoA相位差解算角度 * @param p1:天线1相位 p2:天线2相位 * @retval 入射角度(弧度) */ static float UWB_PDoA_Calc_Angle(float p1, float p2) { float delta = p2 - p1; // 相位差限幅矫正(-π ~ +π) if(delta > 3.1415f) delta -= 2*3.1415f; if(delta < -3.1415f) delta += 2*3.1415f; // 角度解算核心公式 float sin_theta = (delta * UWB_WAVE_LEN) / (2 * 3.1415f * ANT_DISTANCE); // 限幅防止反正弦溢出 if(sin_theta > 1.0f) sin_theta = 1.0f; if(sin_theta < -1.0f) sin_theta = -1.0f; return asin(sin_theta); } /** * @brief 极坐标转直角坐标定位 * @param dist:TWR测距距离 rad:角度弧度值 * @retval 无 */ static void UWB_Polar_To_XY(float dist, float rad) { uwb_twr_handle.pdoa_pos.pos_x = dist * cos(rad); uwb_twr_handle.pdoa_pos.pos_y = dist * sin(rad); }4.5 状态机升级:基站端双天线测距+定位逻辑
修改基站TWR_STATE_RECV_POLL状态,新增双天线相位采集与角度解算,完全兼容原有TWR时序与TWR私有协议
case TWR_STATE_RECV_POLL: rx_len = UWB_Recv_Data(uwb_twr_handle.rx_buf, 64, 200); if(rx_len > 0) { rx_sta = TWR_Decrypt(uwb_twr_handle.rx_buf, rx_len, &msg_params); if(rx_sta == RX_OK) { // 双天线分时采集相位 UWB_Antenna_Switch(1); uwb_twr_handle.pdoa_pos.phase1 = UWB_Get_Rx_Phase(); UWB_Antenna_Switch(2); uwb_twr_handle.pdoa_pos.phase2 = UWB_Get_Rx_Phase(); // 解算角度 float angle_rad = UWB_PDoA_Calc_Angle(uwb_twr_handle.pdoa_pos.phase1, uwb_twr_handle.pdoa_pos.phase2); uwb_twr_handle.pdoa_pos.angle_deg = angle_rad * 180 / 3.1415f; // 记录测距时间戳(原有TWR逻辑不变) uwb_twr_handle.twr_data.anchorinfo[0].poll_rx_timestamp = UWB_Get_Timestamp(); uwb_twr_handle.state = TWR_STATE_SEND_ACK; } } break; // 在TWR_STATE_CALC_DIST后新增坐标解算 case TWR_STATE_CALC_DIST: { // 原有DS-TWR距离计算逻辑不变 uint32_t t1 = uwb_twr_handle.twr_data.poll_tx_timestamp; uint32_t t2 = uwb_twr_handle.twr_data.anchorinfo[0].poll_rx_timestamp; uint32_t t3 = uwb_twr_handle.twr_data.anchorinfo[0].ack_tx_timestamp; uint32_t t4 = UWB_Get_Timestamp(); float tof = (( (t2 - t1) + (t4 - t3) ) / 2.0f) * UWB_TS_UNIT; float raw_dist = tof * UWB_LIGHT_SPEED; uwb_twr_handle.distance_m = UWB_TWR_Filter(raw_dist); // 新增:距离+角度 解算XY坐标 float angle_rad = uwb_twr_handle.pdoa_pos.angle_deg * 3.1415f / 180.0f; UWB_Polar_To_XY(uwb_twr_handle.distance_m, angle_rad); twr_retry_cnt = 0; uwb_twr_handle.state = TWR_STATE_IDLE; break; }4.6 新增坐标输出接口
/** * @brief 获取UWB定位XY坐标 * @retval 定位坐标结构体 */ UWB_PDoA_PosTypeDef UWB_TWR_Get_Position(void) { return uwb_twr_handle.pdoa_pos; }五、调试输出适配(main.c)
while(1) { UWB_TWR_Process(); float dist = UWB_TWR_Get_Distance(); UWB_PDoA_PosTypeDef pos = UWB_TWR_Get_Position(); // 打印测距与定位坐标 STAR_SE_UART_Printf("Dist:%.2fm, X:%.2fm, Y:%.2fm, Angle:%.2f°\r\n", dist, pos.pos_x, pos.pos_y, pos.angle_deg); HAL_Delay(500); }六、关键工程注意事项
天线校准:双天线必须严格平行、间距固定10cm,安装无遮挡、无倾斜,否则角度解算偏差极大
射频参数统一:所有设备信道、PRF、前导码参数保持一致,沿用原有TWR私有协议固化参数
切换时序稳定:天线切换后必须预留1ms稳定延时,避免相位采集异常
相位溢出矫正:代码内置±π相位差限幅,规避相位跳变导致的角度突变
完全兼容原有协议:标签端无需任何修改,仅基站升级双天线逻辑,组网零改动
七、方案优势总结
单基站定位:摒弃传统3基站交会模式,大幅降低部署成本与施工难度
协议无缝兼容:基于原有TWR私有协议与DS-TWR架构,无需重构业务逻辑
高精度融合:TWR测距(±5cm)+PDoA测角(±3°),整体定位精度可达10cm级
平台适配性强:全部代码适配STAR_SE Cortex-M平台,可直接编译烧录运行
容错稳定性高:继承原有滤波、异常重传机制,新增坐标防抖,适配工业场景