Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
MM2WayRanging/MM2WayRanging.cpp
- Committer:
- manumaet
- Date:
- 2015-03-08
- Revision:
- 45:01a33363bc21
- Parent:
- 44:2e0045042a59
- Child:
- 46:6398237672a0
File content as of revision 45:01a33363bc21:
#include "MM2WayRanging.h"
MM2WayRanging::MM2WayRanging(DW1000& DW) : dw(DW) {
isAnchor = true;
overflow = false;
address = 0;
rxTimestamp = 0;
timediffRec = 0;
timediffSend = 0;
for (int i = 0; i < 10; i++)
acknowledgement[i] = true;
dw.setCallbacks(this, &MM2WayRanging::callbackRX, &MM2WayRanging::callbackTX);
//Timer for debugging purposes
LocalTimer.start();
dw.startRX();
}
void MM2WayRanging::callbackRX() {
dw.readRegister(DW1000_RX_BUFFER, 0, (uint8_t*)&receivedFrame, dw.getFramelength());
if (receivedFrame.destination == address)
switch (receivedFrame.type) {
case PING:
rxTimestamp = dw.getRXTimestamp();
receiverTimestamps[receivedFrame.source][0] = rxTimestamp; //Save the first timestamp on the receiving node/anchor (T_rp)
sendDelayedAnswer(receivedFrame.source, ANCHOR_RESPONSE, rxTimestamp);
break;
case ANCHOR_RESPONSE:
rxTimestamp = dw.getRXTimestamp();
senderTimestamps[receivedFrame.source][1] = rxTimestamp; //Save the second timestamp on the sending node/beacon (T_rr)
sendDelayedAnswer(receivedFrame.source, 3, rxTimestamp);
break;
case BEACON_RESPONSE:
rxTimestamp = dw.getRXTimestamp();
receiverTimestamps[receivedFrame.source][2] = rxTimestamp; //Save the third timestamp on the receiving node/anchor (T_rf)
correctReceiverTimestamps(receivedFrame.source); //Correct the timestamps for the case of a counter overflow
//calculation of the summand on the receiving node/anchor
timediffRec = - 2*receiverTimestamps[receivedFrame.source][1] + receiverTimestamps[receivedFrame.source][0] + receiverTimestamps[receivedFrame.source][2];
sendTransferFrame(receivedFrame.source, timediffRec );
break;
case TRANSFER_FRAME:
//calculation of the summand on the sending node/beacon
timediffSend = 2 * senderTimestamps[receivedFrame.source][1] - senderTimestamps[receivedFrame.source][0] - senderTimestamps[receivedFrame.source][2];
//calculation of the resulting sum of all four ToFs.
tofs[receivedFrame.source] = receivedFrame.signedTime + timediffSend;
acknowledgement[receivedFrame.source] = true;
break;
default : break;
}
dw.startRX();
}
void MM2WayRanging::callbackTX() {
switch (rangingFrame.type) {
case PING:
senderTimestamps[rangingFrame.destination][0] = dw.getTXTimestamp(); //Save the first timestamp on the sending node/beacon (T_sp)
break;
case ANCHOR_RESPONSE:
receiverTimestamps[rangingFrame.destination][1] = dw.getTXTimestamp(); //Save the second timestamp on the receiving node/anchor (T_sr)
break;
case BEACON_RESPONSE:
senderTimestamps[rangingFrame.destination][2] = dw.getTXTimestamp(); //Save the third timestamp on the sending node/beacon (T_sr)
correctSenderTimestamps(rangingFrame.destination); //Correct the timestamps for the case of a counter overflow
break;
default:
break;
}
}
/**
* Get the distance to the Anchor with address @param destination.
*
* @param destination The address of the anchor
*/
void MM2WayRanging::requestRanging(uint8_t destination) {
acknowledgement[destination] = false;
float time_before = LocalTimer.read();
sendPingFrame(destination);
while(!acknowledgement[destination] && (LocalTimer.read() < time_before + 0.5f)); // wait for succeeding ranging or timeout
roundtriptimes[destination] = LocalTimer.read() - time_before;
if(acknowledgement[destination]){
distances[destination] = calibratedDistance(destination);
} else {
distances[destination] = -1;
}
}
inline float MM2WayRanging::calibratedDistance(uint8_t destination) {
float rawDistance = (tofs[destination] * 300 * TIMEUNITS_TO_US / 4);
if (this->address == 1) rawDistance+= 10;
switch(destination){
case 2:
return rawDistance * 0.9754 - 0.5004;
case 3:
return rawDistance * 0.9759 - 0.4103;
case 4:
return rawDistance * 0.9798 - 0.5499;
case 5:
return rawDistance * 0.9765 - 0.5169;
}
}
void MM2WayRanging::requestRangingAll() {
for (int i = 1; i <= 5; i++) { // Request ranging to all anchors
requestRanging(i);
}
}
void MM2WayRanging::sendPingFrame(uint8_t destination) {
rangingFrame.source = address;
rangingFrame.destination = destination;
rangingFrame.type = PING;
dw.sendFrame((uint8_t*)&rangingFrame, sizeof(rangingFrame));
}
void MM2WayRanging::sendTransferFrame(uint8_t destination, int timeDiffsReceiver) {
transferFrame.source = address;
transferFrame.destination = destination;
transferFrame.type = TRANSFER_FRAME;
transferFrame.signedTime = timeDiffsReceiver; //cast the time difference
dw.sendFrame((uint8_t*)&transferFrame, sizeof(transferFrame));
}
void MM2WayRanging::sendDelayedAnswer(uint8_t destination, uint8_t type, uint64_t rxTimestamp) {
rangingFrame.source = address;
rangingFrame.destination = destination;
rangingFrame.type = type;
if(rxTimestamp + ANSWER_DELAY_TIMEUNITS > MMRANGING_2POWER40)
dw.sendDelayedFrame((uint8_t*)&rangingFrame, sizeof(rangingFrame), rxTimestamp + ANSWER_DELAY_TIMEUNITS - MMRANGING_2POWER40);
else
dw.sendDelayedFrame((uint8_t*)&rangingFrame, sizeof(rangingFrame), rxTimestamp + ANSWER_DELAY_TIMEUNITS);
}
void MM2WayRanging::correctReceiverTimestamps(uint8_t source){
if(receiverTimestamps[source][0] > receiverTimestamps[source][1]){
receiverTimestamps[source][1] += MMRANGING_2POWER40;
receiverTimestamps[source][2] += MMRANGING_2POWER40;
}
if(receiverTimestamps[source][1] > receiverTimestamps[source][2]){
receiverTimestamps[source][2] += MMRANGING_2POWER40;
}
}
void MM2WayRanging::correctSenderTimestamps(uint8_t source){
if (senderTimestamps[source][0] > senderTimestamps[source][1]) {
senderTimestamps[source][1] += MMRANGING_2POWER40;
senderTimestamps[source][2] += MMRANGING_2POWER40;
overflow = true;
} else if (senderTimestamps[source][1] > senderTimestamps[source][2]) {
senderTimestamps[source][2] += MMRANGING_2POWER40;
overflow = true;
}else overflow = false;
}