about TDOA

All discussions related to the Loco Positioning system
justinleeyang
Expert
Posts: 186
Joined: Mon Dec 28, 2015 5:07 am

about TDOA

Post by justinleeyang »

Hi, arnaud:
I have already notice your TDOA code, how to understand the following commit?

* Each packet contains (assuming the packet is sent by anchor n):
* - The time the packet was sent in A0 clock. Not used by the anchors.
* - A list of 8 timestamps that contains
* - At index n: The TX timestamp of the current packet in anchor n time
* - At index != n: The RX timestamp of all other packets from previous
* frame in anchor n clock.

especially, at index !=n case.
arnaud
Bitcraze
Posts: 2538
Joined: Tue Feb 06, 2007 12:36 pm

Re: about TDOA

Post by arnaud »

Hi Justin,

The TDoA anchors works by sending 1 packet each in sequence. So from outside you will see packets coming from anchors 0, 1, 2, 3, 4, 5, 6, 7 and then back to 0, ....

For each packets there is 8 timestamp generated by the system: the transmit time of the packet and the receive time in all the other anchors.

This is the 8 timestamps that are contains in the packets: the tx time of the current packet, and the rx time of the 7 latest other anchors packets.

This is enough information to calculate the clock drift and offset for any anchor and the Crazyflie is currently doing the calculation to synchronize all the anchors to anchor 0. Later we will be able to calculate that in the anchors as well to simplify the Crazyflie code.
justinleeyang
Expert
Posts: 186
Joined: Mon Dec 28, 2015 5:07 am

Re: about TDOA

Post by justinleeyang »

hi, arnaud:

Anchor0 (Master) also need receive the other anchor 1~7's packet ? then the next loop anchor0 will send tx timestamp and previous receive timestamp.
anchor0 should not need record the other anchor's information, it can only send packet. other anchor receive firstly, then send to tag. right?
arnaud
Bitcraze
Posts: 2538
Joined: Tue Feb 06, 2007 12:36 pm

Re: about TDOA

Post by arnaud »

Hi Justin,

If you want to be able to measure the distance between A0 and the other anchors, A0 needs to listen to everyone else. Though if you only want to synchronize to A0, the other anchor do not need to listen to each-other: they only need to listen to anchor 0.

We implemented the anchors that way so that we transmit in the air the complete information content that can be generated by the system. That way we can synchronize any anchor against each other and start experimenting with things like floating system clock and automatic anchor position estimation.

There is a field in the anchor packet for TX time in system clock, when we have the system working with synchronizing with anchor 0 we will fill-up this field with the TX time at anchor 0. If we devise a more clever algorithm in the future we can change the TX time in system clock as calculated with the new algorithm.

/Arnaud
justinleeyang
Expert
Posts: 186
Joined: Mon Dec 28, 2015 5:07 am

Re: about TDOA

Post by justinleeyang »

Hi, arnaud:

Got it, Thanks!
justinleeyang
Expert
Posts: 186
Joined: Mon Dec 28, 2015 5:07 am

Re: about TDOA

Post by justinleeyang »

hi, arnaud:

I have already see that your TDOA can work. and I will try it. A question:

don't understand the following commit:
rxAr_by_An_in_cl_An should be interpreted as "The time when packet was received from the Referecne Anchor by Anchor N expressed in the clock of Anchor N"
and the parameter:
rxAr_by_An_in_cl_An, previuos_rxAr_by_An_in_cl_An and rxAn_by_Ar_in_cl_Ar.
justinleeyang
Expert
Posts: 186
Joined: Mon Dec 28, 2015 5:07 am

Re: about TDOA

Post by justinleeyang »

hi, arnaud:

according to my understand TDOA code, if only use 4 anchors and a tag, I draw the processing, and mark the paramter, right ?
TDOA and TWR - Page 1.png
arnaud
Bitcraze
Posts: 2538
Joined: Tue Feb 06, 2007 12:36 pm

Re: about TDOA

Post by arnaud »

Hi Justin,

Your drawing looks correct.

Currently the TDoA algorithm we are using is not using a single anchor as master. When the Crazyflie receive a sequence of packet, for example A0 then A1, A0 will be the reference (Ar) and A1 will be An in the equations. When then receiving A2, A1 becomes the reference Ar and A2 becomes An. That way we can synchronize one anchor to its closest neighbor time-wise.

Then your drawing is correct for anchors A0-A1. If we consider A0==Ar and A1==An, the timestamps are used to:
- Calculate the clock skew of An versus Ar
- Calculate the distance, in time of flight, between Ar and An, expressed in Ar clock.
- Calculate the tag clock skew versus Ar
- Calculate the difference of time between the latest transmission time of Ar and An expressed in Ar clock versus the difference of reception time by the tag expressed in Ar clock.

Doing so we get the difference of time of flight of the two packets, and we can feed the distance difference in the Kalman Filter.
justinleeyang
Expert
Posts: 186
Joined: Mon Dec 28, 2015 5:07 am

Re: about TDOA

Post by justinleeyang »

hi, arnaud:

I think that the following 4 parameters mark right:

Code: Select all

    const int64_t previous_rxAn_by_T_in_cl_T  = arrivals[anchor].full;
    const int64_t rxAn_by_T_in_cl_T  = arrival.full;
    const int64_t previous_txAn_in_cl_An = timestampToUint64(rxPacketBuffer[anchor].timestamps[anchor]);
    const int64_t txAn_in_cl_An = timestampToUint64(packet->timestamps[anchor]);
But others, I don't understand, for example, we calculate the tof A0(Ar) to A1(An), the code as follow:

Code: Select all

const int64_t tof_Ar_to_An_in_cl_Ar = (((truncateToTimeStamp(rxAr_by_An_in_cl_An - previous_txAn_in_cl_An) * clockCorrection_An_To_Ar) - truncateToTimeStamp(txAr_in_cl_Ar - rxAn_by_Ar_in_cl_Ar))) / 2.0;
according to my mark, no get the fly time from A0 to A1, the code:

Code: Select all

truncateToTimeStamp(rxAr_by_An_in_cl_An - previous_txAn_in_cl_An) 
why is previous_txAn_in_cl_An rather than txAr_in_cl_Ar ? and why include previous tx timestamp rather than current tx timestamp?
arnaud
Bitcraze
Posts: 2538
Joined: Tue Feb 06, 2007 12:36 pm

Re: about TDOA

Post by arnaud »

Hi Justin,

To measure time of flight, if you know the clock drift between two anchor, you only need to have the timing of one "ping-pong" event. This is what the line you copied do: it uses the packet transmitted by 1 previously with the latest packet transmitted by 0 in order to calculate the time of flight between 1 and 0. The reason we use previous is because we do not have the receive time in clock 0 of the packet from 1 we just received: this time will be contained in the next packet from 0.

The truncateToTimeStamp() is there to handle clock wrapping: the 40Bit timer from the DWM1000 will wrap every 17 second, if we have two timestamps around a wrapping we need to make sure the difference is still working. The truncateToTimeStamp() truncate the difference to 40Bit to guarantee it always works even if a clock wrapping occurred.
Post Reply