-
-
Notifications
You must be signed in to change notification settings - Fork 885
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Full resolution mode #1572
Full resolution mode #1572
Conversation
-- Rate changed to 4 bits -- Switch mode just one bit -- AUX1 always in high bit of switch byte
I'll provide more concise details about the exact changes to the OTA layouts in this post. This is in progress! OTA ChangesSwitch mode changed to 1 bitThe OTA for even our regular modes has been changed to only be 1 bit for the switch mode, down from 2. We have so many RF modes that we needed more space in the sync packet and honestly I don't even think we need two switch modes on regular ELRS. Wide switch mode is now the default too. The 8ch/12ch flag is sent in every packet in full mode, so switch mode is irrelevant for full mode. Encoding of existing rates CH0-CH3 changedIt made sense to make all the 4x 10-bit channels use the same OTA format so a single function could be used. Rather than using our current (8 + 8 + 8 + 8 + 2:2:2:2) encoding, I've made them all use the CRSFv3 format. Values are packed little-endianish such that bits A987654321 -> 87654321, 000000A9. See To expand the 10-bit value back to CRSF values: Sync channel moved to (N/2)+1The sync channel is at FHSS Hops / 2 currently, but our OTA structure is a different so I wanted to break compatibility with 2.0 systems and reduce the chance of them connecting. This can be removed if we can come up with something better, since it is possible that a 2.0 system can see a 3.0 syncspam packet and misinterpret it still. Air rate mode indexes changedSPI can just ignore any air rate it does not support Team 900
Team2.4
Misc
|
# Conflicts: # src/lib/SX1280Driver/SX1280.cpp # src/lib/SX1280Driver/SX1280_hal.cpp # src/lib/SX1280Driver/SX1280_hal.h # src/src/tx_main.cpp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Theres nothing really to complain about here! Nice job.
I'll fix the remaining merge conflicts tomorrow morning as I'll have a little time then. |
Since we are changing OTA encoding, lets go all the way for FLRC and just send the 11b channel 😃 This means we get the absolute most out of the current crsf version, double the resolution from existing releases, and remove any weird rounding going from the crsf 10.5b, to 10b OTA, back to 10.5b, then BF scaling to the 10b range but as a float. The change fits the topic of this PR, but we can do it in another since this is already a monster to review/test? |
I hope you're joking. I spent months with this kicking around in my head, drafting ideas and running math trying different encoding parameters and OTA layouts for all the packets. Over two full time weeks hand tweaking code, comparing size and performance, and validating with dozens of hours of bench testing on top of the development time. Why not just throw together a third whole OTA format for some existing air rates a week before the feature freeze?
It is shocking to me how absurd an idea this is just a few days from the feature freeze, with the careful consideration that needs to be given to such a change. I dunno 11bit would be more. 🤪 It would be more but I'm certain it is worse* Asterisk- unless you need 885-2135us for your quad. Do I need to find your quote from last week we're.you said longer OTA duration was a nonstarter for FLRC because of how sensitive it is to interfere. |
FLRC has 14 free bits from the CRC. |
Ah that's right. I misunderstood what you intended and I didn't have much time to try to get there. I guess what we'd do is
It's just throwing more rx/tx packet handler complexity and a whole new set of OTA serializers, and now really this PR shouldn't be reviewed yet because all air rates and switch modes are going to have to run through code paths that touch all that new code. I'm converting this back into draft status until all that's done. |
@CapnBry my preference would be to get this in as-is, especially since @pkendall64 has given it the thumbs up. |
My only thoughts are for the RC packet. Reserve space for 12b channels even though only 11b is needed for current crsf channels. And as you mentioned a bit to describe the nonce slot. |
I'd be happy with that, as this is a pretty big change. Not only would there be new packers/unpackers, but the core code can no longer use the packet size to determine the encoding, and the main code needs separate codepaths to divert to writing to the proper place in the structures. It might be better saved for the next OTA version we'll probably want to do ~6 months from now for other reasons not yet discovered. The "10-bit" from this PR already has much improved precision compared to "10-bit" in OTA 2.x, now having a 1-to-1 mapping from 988-2012, vs around 1-to-1.2 for the latter.
If we're going to change the Channels packet, then there's no reason to not do the other changes as well. The bit allocation for the channels in that packet are up to you, 12-bit reduced range CRSF (988-2012) is fine by me as the switch channels aren't really that important after fullres is available. Going from 5 bytes of payload to 7 for MSP and Adv.Telem, plus 2 extra bytes in the Linkstats Telem is huge though for things like F1000 Airport (more than 40% more throughput) so I feel like if we're going to make an OTA4F, it definitely should do all the packet types. With the benefits of the increased precision this PR already adds to the regular OTA4, would you be on board with delaying these changes to the next OTA version? We could also use that time to actually get 11 full bits and 12 bit reduced range from the handset, by working with EdgeTX to implement CRSFv3's arbitrary resolution packed channels. |
Sounds good |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Flew both 333hz and 100hz using the new "Std" tlm mode...
Tested switching modes on the bench and the older modes still worked (just flicking sticks in BF configurator)
Tested 12ch and 16ch modes on the bench
Tested a pot on a non stick channel, and noted the resolution
Any defects we find can be fixed on master as we discover them, since were committed to full res for 3.0 anyway
* OTA: packets to use structure instead of direct byte handling * Add be32toh * Fix OTA for 3 bit rate index / broken wide support * Break OTA compatibility and config -- Rate changed to 4 bits -- Switch mode just one bit -- AUX1 always in high bit of switch byte * First working refactored for fullres * Put BLE back in, fix errant paren * CrC != cRc * Fix dbg_linkstats decoding for 8ch * Remove debug cruft * Stubborn no longer requires blank packet to complete * Update tests for new sender behavior * Fix original modes not working * Delay jump to wifi on MSP * Fix adv.telem on 4ch rates * Add Team900 100Hz fullres mode * Use FHSS+1 for Wide switch mode init * Add 16ch mode * Refactor PackedRCdataOut to ChannelData * Remove IsArmed from RX/TX * Forgot about my PWMPs * Push switchmode change to main thread * Prevent rate change that changes switchmode when connected * No servo jumps on 16ch mode as the mode changes * Replace statusComplete * Fix automatic switchmode change * Lua sequential loader => queue for reloadRelatedFields * Add missing OLED/TFT screen labels for modes * RGB rate hue is now just a index * 255 / MAX * PayloadLength to determine OTA format instead of Rate * Fix DEBUG_FREQ_CORRECTION overflowing the SNR field * You dummy, you know MAXINT7 is -64 to 63 * Fix calls to OtaUpdateSerializers after criteria change * Revert allowing single packet Stubborn transfers If the entire transfer takes place on the 0th packageIndex the receiver can't discriminate a resend of a packet tail from a new send, which flips the confirm bit and starts a cascading failure until RESYNC * collectgarbage after each string build And some other incredibly minor code reduction * Typo in field type bitmask * Slightly more realistic TLM bandwidth for fullres * Fix tests now that they are working again WOOHOO.exe * Tests for OTA8 * Fix UINT10_to_CRSF only going to 1999 for 2000 input * Smaller RcPacketToChannelsData using common bitpacker * Unncessary volatiles * Remove unitended change from 79de904 * TX MSP functions only if !CRITICAL_FLASH * Clarifying comment * Fix DEBUG_CRSF_NO_OUTPUT for RCframes * Return of F500 * More efficient byte packing of rates/mod settings * Use full 10-bits for 988-2012 for OTA4 main channels * SNR uses the whole OTA field now, is signed * Fix DEBUG_RCVR_LINKSTATS compile errors * You miss ONE merge problem, github all up in your business * Fix failed merge attempt * Return F500 to display * RATE_DEFAULT back to 0 * Return F500/F1000 to 2 hops * Missed the TLM differences Co-authored-by: cruwaller <cruwaller@gmail.com> Co-authored-by: Paul Kendall <pkendall64@gmail.com>
I'm confident enough that I've started doing real flight testing with it, but be very careful. If something doesn't look right, don't fly! Plug in with caution in case I've messed something up and your motors spin up somehow, and check your LQ to verify 100 before taking off.
Two new modes
Selectable channel count
8ch and 12ch modes actually has one extra channel, AUX1 which is still 1-bit, but I didn't want to include that in the channel count because everyone hates AUX1 anyway. 8.1ch and 12.1ch?! 😏
Improved telemetry bandwidth
At our standard rate (4Hz telemetry) the current modes only have 10 bytes of telemetry bandwidth per second. The fatter packet means we can send ~2.4x more data per second at the basic rates. These modes also do not require a dedicated telemetry slot for LinkStats. When sending LinkStats, the advanced telemetry bandwidth is just slightly reduced for that packet.
Faster telemetry for all
In addition to that! The Stubborn telemetry transfer system currently always has to send a blank packet at the end of every item it transfers as the final ACK message to complete the transfer. Sending the typical VBAT telemetry of 12 bytes this goes in chunks 5-5-2-0. The code has been changed to accept the final ack on the "2" packet instead of requiring a separate "0" packet. For the VBAT example this transfers 25% faster. However, no single packet transfers are possible, as the receiving end needs to be able to discriminate a new transfer from the tail of a multi-packet resend that wasn't acked.
Due to changes being needed in the StubbornSender/Receiver classes that require them to be fully revalidated, this works its way in to this PR too.
Improved precision for original modes
Our current OTA we call "10 bit", however the way the ~10.9 bit CRSF data is decimated down to 10 bit is simply to divide it by 2. But! CRSF supports partial E.Limits i.e. beyond the 988 to 2012 range. For quads, this precision is wasted, meaning we only ever fill 80% of our 10 bit range with data. I'm changing that so our normal 4ch OTA uses all 10 bits to store 988-2012 and clamps any input outside that range, thus increasing our precision for our standard modes by 25%. Fullres mode is unaffected and supports the full CRSF range (885us - 2115us).
Always includes TPwr
The TX power level is included in the uplink packet in all Full modes, not just limited to Wide switch mode any more.
Why half/third/quarter rate small packets sucks
The simplest way to add more fullres channels is to just to halve our effective rate and just rotate though all the channels, right?!
0.6 OTA x 0.8 tock slack x 0.625 protocol overhead -> 30% of each period is spent actually transferring usable data and the 70% is overhead. If we want to send 8 full channels, we'd have to split that in half, and 12 channels would reduce it to a third.
A fatter packet just works better since all those overheads listed above are fixed per packet.
0.75 OTA x 0.8 tock slack x 0.77 protocol overhead -> 46% of time used actually transferring data or more than a 50% improvement in raw bandwidth. For transferring 8 full channels, that's a 100% improvement over 500Hz with round robin!
Downside
There's no denying that a packet that can be transferred more quickly is slightly more robust to random interference than a larger one. The technical term is putting all your eggs in one basket. In practice this doesn't appear to be significant, and nobody is complaining that our current lower rate modes perform worse, right?
Y U NO make rate slower
This is not about range, this is about precision. What good is a 10-bit channel going to do for smoothness when it is operating at 30Hz or less? SF7 is a good balance between update rate and range-- 4dBm more sensitive than our 250Hz mode that has done 40km. The encoding was chosen to give 12ch at 100Hz+50Hz, or 8ch all at 100Hz. Upping to SF8 would mean 12ch at 34Hz for just 3dBm more sensitivity.
Superseded PRs and Implementation Stuff
Built on 1421
#1421 "OTA packets to use structure instead of direct byte handling" was used as the base for this PR.
Prevent switch mode change while connected
It makes sense to put a check on the RX to prevent a switchmode change while connected, so this PR supercedes #1540 "More switchmode guard" and prevents the change. This PR also contains the Ota changes from #1540, which were then resubmited as #1567 "common 5 main channel same encoded". Confused at all?
The code now only allows a switchmode change on the RX if it is disconnected. It does this now by pushing the change to the main thread and blocking all RC channels packets until the mode changes.
Lua field peer refresh
Changing the packet rate now changes what the switch mode values are, so the Lua needs to reload to some degree. On master it is also broken that changing the
Packet Rate
changes the TLM bandwidth, but that doesn't update because it is a different field.Now when a field value is changed, all of the same-level editable items are reloaded. For example, changing Packet Rate reloads Packet Rate first, then TLM Ratio, then Switch Mode, then Model Match. This is implemented as a loading queue, replacing the older sequential field ID counter. Somehow the loadQ system ends up being smaller too because it is simpler.
I've also removed the float type Lua handlers and the ability to edit strings. We do not use these so it makes the script smaller to not include them and save the RAM.
Unintentional Fixes
TODO
Provide updated OTA specs for spi-devWe are so out of RATE colors for the haz RGB crowd, so I dunno what we can do about that because Jye's got two other rates too with DVDA. Maybe color them by sensitivity instead?Because changing the packet rate now changes what the switch mode values are, the Lua should update everything at the same level when a value is changed. This will also fix the TLM ratio bandwidth not updating when you change the packet rate which is currently broken in masterAdd 100hz fullres mode for Team900. This is easy just haven't done it yet.The StubbornSender seems to always start out of sync with the other end and takes a bunch of packets to reset. I'll figure that out.Now that I am doing more rigorous testing, it is clear that the old modes aren't working any more. They were earlier yesterday! I'll fix this16ch modeChanging switchmode on the RX needs to probably be moved out of the received-packet ISR, as the function it calls is not IRAM and I don't want it to be. I might split the switchmode setter out? Or maybe have it update in the main loop instead like the rate change