g3gg0 / ESP32_CRSFSniffer

MIT License
62 stars 14 forks source link

CRSF Packet Sequence Number #5

Open rogercrsf opened 1 year ago

rogercrsf commented 1 year ago

Hey @g3gg0, thank you for sharing this sniffer I've studied a lot from this blog post of yours https://www.g3gg0.de/wordpress/fpv/fpv-analysis-of-tbs-crossfire/

I'm looking for a solution to aggregate several physical links into one, so looking for a way to identify the sequence number of a packet to decide which one to execute considering I have two receivers connected to Flight Controller.

I'm playing with a simple Python parser(which is quite similar to your C# parser) in order to analyse CRSF packet, my goal is to find out how CRSF protocol identifies actuality of a packet, like how it decides that current packet is "old" and it should be dropped.

What I mean, theoretically, it is possible that for example B packet is received first compared to A, while transmitter sent A first and then B.

So how the receiver does know which packet should be "executed" and which is to drop? I guess there should be some sequence number or similar, but how one can parse/know it?

Could you please provide any hint in case you have any knowledge on that? I'm motivated enough to compensate you the time spent on that, please.

I was looking into bunch of the directions already. Found this spec - https://www.openrcforums.com/forum/download/file.php?id=17402, but it says nothing about sequence number, only defines packet types and their size + some more information. From that (and from your material) I learned that I need to analyse 0x16 packet, which is RC channels packed. And I've identified which channel corresponds to the my joystic moves. Like here it is sent with 14s channel, I see how the value differs, when I change joystic position: image

But how one can identify the sequence number of a packet, I afraid it is handled at RX side itself, and I cannot see this information when RX sends instructions to Flight Controller? Is there a way still get this info somehow?

g3gg0 commented 1 year ago

the packets are sent one after another at a monotonic rate. for this reason the protocol doesn't need any sequence number to reorder or to realize that a packet was lost.

if it doesn't appear in time, it was lost and the receiver switches to the next frequency the hopping sequence defines.

so there is no reason to have a frame number and (without checking the data) there won't be a packet number in the protocol at the air link level.

g3gg0 commented 1 year ago

if you want to compensate for timing issues that come with your setup (e.g. because you don't have hardware-synchronized receivers) then you will have to compensate it on this level by - suprise - synchronization :)

rogercrsf commented 1 year ago

so there is no reason to have a frame number and (without checking the data) there won't be a packet number in the protocol at the air link level.

But how checking the data might help? Or by that you mean there is a way to pass data with each packet and it is a matter of having custom firmware on transmitter? Yea, if that is a possibility, I'd appreciate a hint on where to start doing this

then you will have to compensate it on this level by - suprise - synchronization :)

Could you please clarify on what you mean by "this level" please? Meaning on a higher session-application levels?

g3gg0 commented 1 year ago

But how checking the data might help?

in other words: "i didn't double-check the data, but i am quite certain there is no frame/packet number"

i do not know the exact use case of your solution. do i do not know the design criteria.

assumption: you want to build a master/slave system where the master can take over by moving a stick. in this case you have two physical isolated transmitters and -probably- also receivers.

this implies:

thus you probably would have to build your own "schedule" which may be free-running, synchronized or averaged both transmitters' schedules and interpolate the received data to match your target clock.

here a sketch visualizing my point with drifting clocks (which is absolutely normal and to expect) grafik

there you can see the orange/blue lines to get out of sync (even being in synchronization at some point in time is pure accident)

now you in front of the monitor have to know what to do when this or that happens. plan your design criteria.

rogercrsf commented 1 year ago

both transmitters' clocks will have independent drift and jitter Isn't there a way to synchronise transmitters clocks?

Yea, my plan was to have my Tango device being wired to two transmitters, like T1 and T2, which "talk" to R1 and R2 receivers correspondingly, I'm not quite sure about how technically that is possible (and if clocks are being synchronized in that case), but the guy selling me a dron, said it is possible, like T1-R1 will make Path1 over 915MHz and T2-R2 over 450MHz implementing Path 2 from your illustration.

I need to implement something similar to Ethernet link aggregation, and I'm pretty opened to any suggestion. The purpose is to have scalable redundancy architecture, meaning 2 and more physical links to be aggregated into one logical virtual link. So if Path1 is low, we will go Path2 and vice versa.

But my idea was to have a way to identify each packet and at Flight Controller level have a virtual receiver, that will be listening traffic from both receivers and decide which one to forward to Flight Controller depending on last processed packet sequence number and current packet numbers read from R1 and R2.

In any case, even with master/slave architecture and with no clock synchronisation that you described it does not really matter, if I teach the transmitter to assign each packet a sequence number in a way that both Path 1 and Path 2 will be sending packets with equal sequence number, so then I decide from virtual receiver which packet to process depending on last processed sequence number and current numbers.

Please let me know if anything above makes any sense or if I'm missing something important here?

btw, thanks for your replies :)

g3gg0 commented 1 year ago

i am not aware how you could:

for this scenario you would have to be aware that there are multiple layers:

[stick values] okay you just want redundancy (not increasing throughput) for stick values, so you could opt for sending both data always on both channels. you probably do not want "switch" to the other in case of a congestion, but use the last valid stick value payload.

[telemetry] now it gets interesting if you want to increase throughput here. do you want to inject your own data here? or use the data you received from the remote? if you get it from the remote, you cannot squeeze in more to increase throughput... so also just send it twice in parallel and make sure the receiver uses every received packet only once (knowing about both schedules and knowing what to expect when)

g3gg0 commented 1 year ago

on the serial rx/tx protocol (known as the CRSF in all flight controlers etc) you will receive packets like these https://github.com/g3gg0/CRSF_RevEng/blob/master/CRSF_Debug/Program.cs#L26

please note that the serial link and the air link use different protocols, even the stick values being different widths (10 on air vs 11 on serial). so do no expect if you understand the CRSF, you do know what is happing on air link.

rogercrsf commented 1 year ago

Yea, I understand that air link != serial link so, I'm dealing with a serial links, right? I mean I'm playing between remote and Tx and Rx and Flight Controller. Ideally, I do not want touching remote and Tx part.

so also just send it twice in parallel and make sure the receiver uses every received packet only once (knowing about both schedules and knowing what to expect when)

could you please elaborate on this part please? What does it mean "knowing about both schedules" and "knowing what to expect when"? When I read "and make sure the receiver uses every received packet only once" - this sounds like, identify each packet uniquely and just check if this packet was already processed. Isn't it CRC? Hm, but it is not guaranteed to be unique, right?

g3gg0 commented 1 year ago

this sounds like, identify each packet uniquely and just check if this packet was already processed. Isn't it CRC? Hm, but it is not guaranteed to be unique, right?

correct and correct.

maybe i misunderstood the target picture a bit. could you make/update the drawing https://excalidraw.com/#room=c9e325e0604ec7ca7950,YJ9gcyY3W7PJjoCydbRgPA so we have the same understanding of what the setup will be and we talk about the same? we are talking about the part i called "Receiver controller", right?

it shall receive CRSF packets from two Rx devices (like stock nano receivers) and combine them, so it appears as a normal, single Rx to a flight controller. right?

rogercrsf commented 1 year ago

the picture is perfect! and yes - we are talking about "Receiver controller" or I call it virtual controller :)

it shall receive CRSF packets from two Rx devices (like stock nano receivers) and combine them, so it appears as a normal, single Rx to a flight controller. right?

Exactly!

g3gg0 commented 1 year ago

okay then i was partially stuck at some air level implementation (where my main research was). on this level i did not play a lot with CRSF.

with two signals, i see a potential problem that arises when one drops out and you just pass the frames from the other link. then you will have a pause between RC frames which might be too long for the FC controller to handle properly. you would have to check this variant if the FC is stable enough. this might especially arise when you switch between those two links a few times successively. if it is troublesome i'd indeed implement my own schedule that is clocked the same as the target clock and is always soft-synchronized to the current active Rx link. (smoothly stretching/squeezing the schedule length until they are in sync again)

but for the first start: just forward the RC frames from one link, buffer the ones from the second link, measure their Δt and if a frame on the current link was missed, send the last RC frame from the other link and switch over to the other link.

this is a dumb strategy, but maybe the FC is stable enough and you do not notice switches at all. (however if you are doing FPV races and are on pro level it might feel a bit jerky)

rogercrsf commented 1 year ago

Hey, forgot to mention that I'm playing with Arduino scatches now trying to implement some simple algorithm that will identify connectivity issues. Will keep you posted on the progress, thank you for the answers!

Can I donate some how for all the inputs you made, please?

g3gg0 commented 1 year ago

sure, if you want to donate (money usually is used for buying electronics / tinkering equipment like i used here) you can send it to paypal@g3gg0.de thanks!

g3gg0 commented 1 year ago

if you need support, you can also contact me directly. i guess you will find a way, either telegram, mail or here