Some background …
Single sided TWR is depending on:
- total time between transmit of “poll” message in initiator (
poll_tx_ts
) and receive response from responder (resp_rx_ts
) - total time in responder between receive of poll message (
poll_rx_ts
) from initiator and transmit of response to initiator (resp_tx_ts
).
See relevant excerpt from initiator (ex_06a_ss_twr_initiator
) below.
/* Retrieve poll transmission and response reception timestamps. See NOTE 9 below. */
poll_tx_ts = dwt_readtxtimestamplo32();
resp_rx_ts = dwt_readrxtimestamplo32();
/* Read carrier integrator value and calculate clock offset ratio. See NOTE 11 below. */
clockOffsetRatio = ((float)dwt_readclockoffset()) / (uint32_t)(1<<26);
/* Get timestamps embedded in response message. */
resp_msg_get_ts(&rx_buffer[RESP_MSG_POLL_RX_TS_IDX], &poll_rx_ts);
resp_msg_get_ts(&rx_buffer[RESP_MSG_RESP_TX_TS_IDX], &resp_tx_ts);
/* Compute time of flight and distance, using clock offset ratio to correct for differing local and remote clock rates */
rtd_init = resp_rx_ts - poll_tx_ts;
rtd_resp = resp_tx_ts - poll_rx_ts;
tof = ((rtd_init - rtd_resp * (1 - clockOffsetRatio)) / 2.0) * DWT_TIME_UNITS;
distance = tof * SPEED_OF_LIGHT;
See relevant excerpt from responder (ex_06a_ss_twr_responder
) below.
/* Retrieve poll reception timestamp. */
poll_rx_ts = get_rx_timestamp_u64();
/* Compute response message transmission time. See NOTE 7 below. */
resp_tx_time = (poll_rx_ts + (POLL_RX_TO_RESP_TX_DLY_UUS * UUS_TO_DWT_TIME)) >> 8;
dwt_setdelayedtrxtime(resp_tx_time);
/* Response TX timestamp is the transmission time we programmed plus the antenna delay. */
resp_tx_ts = (((uint64_t)(resp_tx_time & 0xFFFFFFFEUL)) << 8) + TX_ANT_DLY;
/* Write all timestamps in the final message. See NOTE 8 below. */
resp_msg_set_ts(&tx_resp_msg[RESP_MSG_POLL_RX_TS_IDX], poll_rx_ts);
resp_msg_set_ts(&tx_resp_msg[RESP_MSG_RESP_TX_TS_IDX], resp_tx_ts);
Distance calculation is then simply the following (pseudo code) which is resonable.
( ( (resp_rx_ts - poll_tx_ts) - (resp_tx_ts - poll_rx_ts) ) / 2 ) * SPEED_OF_LIGHT
What I don’t understand is how the inaccuracy of delayed TX is handled.
dwt_setdelayedtrxtime()
does not make use of the lower 9 bits of the total time stamp.
While the resolution of the time stamp is 15.65 ps (corresponding to 6 mm tof), the resolution of the delayed transmit is 512 times lower i.e. 8 ns (corresponding to 2.4 m tof).
I have confirmed that dwt_setdelayedtrxtime()
result in a roughly even random distribution of delay within the resolution of delay of 8 ns. This means that the distance measurement may vary by 2.4 meters with an even distribution.
The actual time stamp may be retrieved by getting the time stamp AFTER transmission has completed. But as this is available after transmission in responder it cannot be included in the first response message.
I don’t see any way around this than sending an additional message (possible in a following TWR round) that contains the actual accurate TX time stamp to improve accuracy of SS-TWR.
Is this a correct interpretation?
Will SS-TWR sample produce a minimum accuracy of about 2.4 m?