Wbiu / UWB-Tracking-DWM3000

Other
1 stars 0 forks source link

Multiple Tags #2

Open anthony211212 opened 5 months ago

anthony211212 commented 5 months ago

Hello. Does this library support multiple tags?

Wbiu commented 3 months ago

Hi, sorry for the late respond. It`s hardcoded to send pakages to 4 other tags. Please see line 60-70.

anthony211212 commented 1 month ago

How can we increase the number? Do you have any ideas?

Wbiu commented 1 month ago

Yeah it should be posible. If you look at the loop function, you will see there are for loops which will start the ranging for the 4 Tags that I have ( A,B,C,D). Before I go further. Have you successfully getting the distance between 2 devices?

anthony211212 commented 1 month ago

Could you provide a bit more detail? What do you mean by lines 60-70? And which files should I use to program the anchor and tag? What approach should be taken to increase it?

Wbiu commented 1 month ago

If you take a look at the TX firmware, the TX firmware is responsible for starting the ranging. What I meant by "at the lines 60-70" was these messages that are being send to other DWs ( the other devices/the recieving devices (RX) ). I though by giving you these hint ( line 60-70 and the loop funktion) would be enough to modify firmware so it can send a new device/additional device. On the recieving end ( the RX firmware), every package that is not ment to be recieve ( such as wrong ID ) should be ignored.

For example TX firmware lines 60-70 :

static uint8_t tx_poll_msg_A[] = {0x41, 0x88, 0, 0xCA, 0xDE, 'W', 'A', 'V', 'E', 0xE0, 0, 0};
static uint8_t rx_resp_msg_A[] = {0x41, 0x88, 0, 0xCA, 0xDE, 'V', 'E', 'W', 'A', 0xE1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

static uint8_t tx_poll_msg_B[] = {0x41, 0x88, 0, 0xCA, 0xEE, 'W', 'A', 'V', 'E', 0xE0, 0, 0};
static uint8_t rx_resp_msg_B[] = {0x41, 0x88, 0, 0xCA, 0xEE, 'V', 'E', 'W', 'A', 0xE1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

static uint8_t tx_poll_msg_C[] = {0x41, 0x88, 0, 0xCA, 0xFE, 'W', 'A', 'V', 'E', 0xE0, 0, 0};
static uint8_t rx_resp_msg_C[] = {0x41, 0x88, 0, 0xCA, 0xFE, 'V', 'E', 'W', 'A', 0xE1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

static uint8_t tx_poll_msg_D[] = {0x41, 0x88, 0, 0xCA, 0xAE, 'W', 'A', 'V', 'E', 0xE0, 0, 0};
static uint8_t rx_resp_msg_D[] = {0x41, 0x88, 0, 0xCA, 0xAE, 'V', 'E', 'W', 'A', 0xE1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

These are messages that are being transmitted to other 4 DWs. The unique ID that have set are DE,EE,FE,AE . The transmission will begin/start in the loop funktion.

Now in the RX firmware lines 33,34 :

static uint8_t rx_poll_msg[] = {0x41, 0x88, 0, 0xCA, 0xAE, 'W', 'A', 'V', 'E', 0xE0, 0, 0};
static uint8_t tx_resp_msg[] = {0x41, 0x88, 0, 0xCA, 0xAE, 'V', 'E', 'W', 'A', 0xE1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

As you can see this firmware will only accept the unique ID: AE.

So overall the TX firmware will gather all the distance from other DWs and send the distance another ESP over espnow. BUT! you will have to triangulate them to get the correct position.

In my case the transmitting device(TX) is the that is moveable and stationary once are the RXs.

I hope this clears thing up abit for you.

anthony211212 commented 1 month ago

My mind is a bit confused. If we want to do it here with 6 tags and 4 anchors and use triangulation, how should we set it up? As I understand it, the Tx and Rx are reversed here, meaning what we call Tx is used for the tag, and what we call Rx is used for the anchor in this example.

Wbiu commented 1 month ago

Oh I am really sorry I missunderstood you. I dont know why I though you are going to add another Anchor... Sorry from my side. Any way in my case the TX here is the one which is moveable, so it is the Tag.

Wbiu commented 1 month ago

"If we want to do it here with 6 tags and 4 anchors and use triangulation, how should we set it up? " Are you able to get all the distance from 4 of your Anchors with one single Tag?

If the answer is yes. Adding anothoer Tags should be easier I would say. You will have to let one Tag finish its ranging first then let the other one know that they can start ranging now.

anthony211212 commented 1 month ago

I'm a bit new to this, so I apologize. I'd appreciate it if you could guide me. Initially, I took measurements with 4 anchors and 1 tag, but this was with a different library. Then I came across this one and haven't tried it yet. Which method do you think I should follow, and how should I proceed? By the way, I remember the results weren't very good when I measured with 4 anchors and 1 tag. How many anchors and tags did you use exactly, and what were your results?

Wbiu commented 1 month ago

All good. In my case this firmware is using SS-TWR method which is just the original firmware from manufacturer but just modifieded. The SS-TWR method is the simplest way of getting a distance but the results are somewhat noisy so I had smooth things out by reranging the distance of the same Anchor twice and also using the Kalmanfilter to help smoothing the result. Overall the result that I had was okey at most. I believe I've tried 2-3 Anchors and also 1-2 Tags just testing around beck then.

I would look at the original firmware/API qorvo it helps me a lot trying to understand what is going on. There were also example files like SS-TWR, DS-TWR and so on...

UWB ranging is hard to get it very accurate and stable, also this can get very complex very easily. It depens on what you are using it for.

anthony211212 commented 1 month ago

You used the Tx and Rx code files here, right? Also, what exactly does 'twice' represent? Does it mean taking the last two measurements? Additionally, how can we increase the frequency in this code file? I think increasing the frequency might yield better results.

Wbiu commented 1 month ago

Yes I used these codes. Its for 4 Anchors and 1 Tag for tracking my VR-Glove. Yes exactly by twice I meant taking 2 measurement at the same Anchor. TX Firmware loop function:

        for (int i = 0; i < 2; i++)
        {
            ranging_A();
        }

        for (int i = 0; i < 2; i++)
        {
            ranging_B();
        }

As you can see above I first take 2 measurement at Anchor A before moving on to Anchor B.

About the frequency. I believe you cannot directly define which frequency the chip should operate on but you can change the channels. The DWM3000 supports 2 channels. Which are channel 5 (6.5 GHz) and channel 9 (8 GHz). So for example if you set it to channel 5 the chip will operate at 6.5 GHz or if you set it to channel 9 the chip will operate at 8 GHz. That what is the manufacturer says. You can test it out if you want to :)

If take a look at TX Firmware Dwm config, the current channel 5:

static dwt_config_t config = {
        5,               /* Channel number. */
        DWT_PLEN_128,    /* Preamble length. Used in TX only. */
        DWT_PAC8,        /* Preamble acquisition chunk size. Used in RX only. */
        9,               /* TX preamble code. Used in TX only. */
        9,               /* RX preamble code. Used in RX only. */
        1,               /* 0 to use standard 8 symbol SFD, 1 to use non-standard 8 symbol, 2 for non-standard 16 symbol SFD and 3 for 4z 8 symbol SDF type */
        DWT_BR_6M8,      /* Data rate. */
        DWT_PHRMODE_STD, /* PHY header mode. */
        DWT_PHRRATE_STD, /* PHY header rate. */
        (129 + 8 - 8),   /* SFD timeout (preamble length + 1 + SFD length - PAC size). Used in RX only. */
        DWT_STS_MODE_OFF, /* STS disabled */
        DWT_STS_LEN_64,/* STS length see allowed values in Enum dwt_sts_lengths_e */
        DWT_PDOA_M0      /* PDOA mode off */
};
anthony211212 commented 1 month ago

By frequency, I don't mean the operating frequency of the channels. I meant the measurement frequency. By the way, How did you implement the Kalman filter? Additionally, calibration is likely necessary to improve the results

Wbiu commented 1 month ago

Oh okey. Well I think the it depends on many things like the speed of the host controller or like which ranging method you are using and how many caculations you have to do or how much code your host controller has to do and package wait time and so on.... But you can definitely optimize it to your liking.

This is how I implemented the filter. Have a look into the kalmanFilter.h :

Kalman filter_A(0.02, 0.02,0.001);  
distance_A = filter_A.updateFilter(distance_A);

Yes about the calibration. I would have a look in to the user manuel of the chip. They've got some calibration tips in there as well.

anthony211212 commented 1 month ago

It's great that the filter works practically in this way. I think we should look into calibration, because otherwise, correcting erroneous measurements could be more difficult and might reduce accuracy. I was wondering if it's possible to make adjustments to the measurement frequency through the library. I think they must have defined it somewhere in the library.

Wbiu commented 1 month ago

To make it into a realy good and reliable distance measurement requires work.... I would even say a lot of work. I remember back then when I started making an extensive research into this matter, it became more and more complicated and complex to implement. This firmware is just for something to get starting with.

The API is there for you to start digging and see how it work. When looking at the ranging part of the firmware we can already see that we have to manualy start the transmission with "dwt_starttx(...);" or in another way I've put the distance measuring in a seperate function "void ranging_A()" and I mean lets say if this function gets runs 10 per second so you will have 10 measurement in one second and you want to increase to amount of times the function gets executed in a second so you can have more then 10 measurement per second you would have to increase the speed of the execution, which could be the increase of speed of your host processor or optimize different part of the code .... and so on...

To be honest I didnt realy dig all to deep behind the API of the chip. And I also dont know how many packages per second the chip it self can handle.

anthony211212 commented 1 month ago

Which kalman filter library did you use ?

Wbiu commented 1 month ago

https://github.com/denyssene/SimpleKalmanFilter

anthony211212 commented 1 month ago

Things are a bit complicated right now. I don't know if it's because the anchors are close to each other, but I'm reading the tag's position relative to the anchor as if it's on top of the anchor. However, sometimes the system goes off and produces very extreme values. Have you ever experienced this kind of issue?

anthony211212 commented 1 month ago

When I changed the Sleep(RNG_DELAY_MS) command to 50, the system got significantly disrupted. In fact, even with just one tag and four anchors, it causes issues with non-existent values. When using multiple tags and anchors, how did you define them differently? I assume you must have made some changes to tx_poll_msg and rx_resp_msg to achieve this. The system is currently getting worse, so I wanted to ask you about it.

Wbiu commented 4 weeks ago

Have you taken a look at the code in here ? Or over all at the RX and TX firmware in here or the official once? Have you tried a methods like DS-TWR ( this method helps to improove accuracy and there stuff ) or have you TDOA ?

"I assume you must have made some changes to tx_poll_msg and rx_resp_msg to achieve this. " -> Yes. Again line lines 60-70 in the TX firmware:

static uint8_t tx_poll_msg_A[] = {0x41, 0x88, 0, 0xCA, 0xDE, 'W', 'A', 'V', 'E', 0xE0, 0, 0};
static uint8_t rx_resp_msg_A[] = {0x41, 0x88, 0, 0xCA, 0xDE, 'V', 'E', 'W', 'A', 0xE1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

static uint8_t tx_poll_msg_B[] = {0x41, 0x88, 0, 0xCA, 0xEE, 'W', 'A', 'V', 'E', 0xE0, 0, 0};
static uint8_t rx_resp_msg_B[] = {0x41, 0x88, 0, 0xCA, 0xEE, 'V', 'E', 'W', 'A', 0xE1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

static uint8_t tx_poll_msg_C[] = {0x41, 0x88, 0, 0xCA, 0xFE, 'W', 'A', 'V', 'E', 0xE0, 0, 0};
static uint8_t rx_resp_msg_C[] = {0x41, 0x88, 0, 0xCA, 0xFE, 'V', 'E', 'W', 'A', 0xE1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

static uint8_t tx_poll_msg_D[] = {0x41, 0x88, 0, 0xCA, 0xAE, 'W', 'A', 'V', 'E', 0xE0, 0, 0};
static uint8_t rx_resp_msg_D[] = {0x41, 0x88, 0, 0xCA, 0xAE, 'V', 'E', 'W', 'A', 0xE1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

Yes things gets complited when you dive deeper in to the matter. But its a part of learning else things would be too easy ya know.

anthony211212 commented 4 weeks ago

I tried ss-twr and attempted to add trilateration to it. I significantly sped up the system, but after a certain period, it can start producing incorrect results, and a reset is required. I separated the TX and RX I used with different values like 1, 2, 3 based on their IDs.

Wbiu commented 4 weeks ago

The I would suggest that you try DS-TWR. If I remember it correctly the result was better but I ditched doing DS-TWR because it was toooo..... lengthy for me to implement at that time so I stick to SS-TWR. Maybe DW-TWR will give you better result, because those sort of problems accurs more in SS-TWR.

It also took me a few month to get a hang on it like how a RTSL ( Real Time Locating System) works and what is the math behind it and soo on... additionaly I was a beginner in programing as well.