Skip to content
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

Add basic teamrace model select via channel #2176

Merged
merged 23 commits into from Mar 21, 2024

Conversation

CapnBry
Copy link
Member

@CapnBry CapnBry commented Apr 24, 2023

Adds receiver config parameters to allow a channel to be assigned that determines if new channels data is actually forwarded to the flight controller / servos. The intent is to use this for support team racing, such as MultiGP Mayhem.

Team Racing Requirements

Team Racing is defined in this context as:

  • 0 or 1 active transmitters with a distinct binding phrase. "One pilot operating their transmitter"
  • Multiple receivers bound to that transmitter's binding phrase, all powered at the same time.
  • Pilot has the ability to direct which receiver is currently "active" including:
    • Sending channels data and linkstats information to flight controller
    • Transmitting telemetry to the TX
    • Updating servo positions

The purpose of the receiver selection is to allow a downed model (which is physically unreachable) to be deactivated and allow the pilot to take control of another model using the same controller. In a default setup, if the pilot plugged in a new model and armed, both models will respond and arm which is incredibly undesirable.

This can currently be achieved by using Betaflight's Modes tab, Failsafe mode, and assigning ranges for each model where it will force failsafe such as this for only allowing this model to fly if AUX8 is around 1200us
image

Team Racing does NOT:

  • Allow multiple pilots (more than 1 active transmitter) to control a model. There is only one binding phrase and ExpressLRS rule is one active transmitter per binding phrase.
  • Support different packet rates / switch modes per model. All models use the same packet parameters.
  • Encourage pilots to have multiple active models flying at once, e.g. launching a model and putting it into autopilot, then switching to a second model to chase it by effectively failsafing the first via TeamRace switch.

Details

Two new configuration parameters are added to the Receiver Lua (ExpressLRS Lua -> [Other Devices] -> (select receiver item) -> Team Race):

  • Channel (default CH11 / AUX7) TeamRace Channel - The channel that is checked on the receiver to determine the currently selected model. Has no effect if the TeamRace Position is set to Disabled. AUX7 was chosen as the default due to it being the last 2/3/6-pos switch in Hybrid mode and being the 6th real switch it should be out of the way (users won't think they should rearrange all their current switches if the default was, e.g. AUX2, the first real switch)
  • Position (default Disabled) TeamRace Position - Which position of the TeamRace Channel activates this model. 6-position switches are supported (1-6) as well as Low/Mid/High for using a 2 or 3-position switch. This was made just one parameter instead of specifying a microsecond range in two parameters to simplify the configuration.

If TeamRace is active, the first packet containing channel data that has a "teamrace model mismatch" disables telemetry, servo updates, and linkstats updates to the flight controller, but does forward that packet to the flight controller. If two consecutive mismatch packets are received, the connection is fully disabled and no further data will be sent to the flight controller at all after that packet. These two packets allow the FC to have additional logic assigned, such as putting the VTX into Pit Mode via Modes, disabling the VTX via a USER1 Mode, etc.. While in this output inhibited state, the receiver still performs every other operation normally, such as FHSS, LQ calculation, and even changing Packet Rates if requested.

Conversely, it takes two consecutive teamrace model match packets to fully restore the connection to a normal state.

Two consecutive packets are required to make the switch because in my testing a certain major brand transmitter was found to transmit intermediate values when switching between 6-pos positions. Log of switching between 6-pos position 1 (0) and position 6 (5) in Wide switch mode :/ Also provides extra insurance getting to the FC if one of the two packets fails CRC.

Switch to 0 (191)
Switch to 4 (1476) !!!
Switch to 5 (1792)
Switch to 0 (191)
Switch to 5 (1792)
Switch to 0 (191)
Switch to 5 (1728)
Switch to 0 (291)
Switch to 5 (1741)
Switch to 0 (191)
Switch to 5 (1792)
Switch to 1 (493) !!!
Switch to 0 (191)

This code works in Hybrid and Wide switch mode as well as FullRes packet modes. When the receiver is in a TeamRace Mismatch mode, the LED will display the "Model Mismatch" blink pattern / color. The Lua will not display Model Mismatch, as telemetry will be disabled.

NOTE Servos will wait 1s before switching to failsafe positions, which may be longer than normal (LQ dropping to 0 is usually faster than the 1s hard timeout). If this is a dealbreaker, I can have them failsafe immediately when teamraceModelIsSelected() goes false but I don't think it is worth the extra function call which would happen at like 50,000Hz.

VTX Control

It would be faaaaantastic if we could also put the VTX into Pit Mode or shut it down entirely but there are two challenges here:

  • The FC may have hardware control, via a USER1/USER2 Mode or a pinio_box, which can not be controlled directly
  • Setting the VTX to Pit Mode via MSP in Betaflight requires the caller to know the current Channel, Band, and Power level as the MSP_SET_VTX_CONFIG handler does not support just setting the pit mode by itself. This could possibly be done in the future by requesting MSP_VTX_CONFIG to query the values, but this is a complex interaction that would involve hooking the telemetry system. Still it could be done in future versions without too much effort.

No new config version?

The new byte added to the config struct appears to be already zeroed when coming from config version 7 / master and therefore will default to TeamRce Ch = AUX2, TeamRce Pos = Disabled. Not exactly the same defaults but it is disabled which is all that matters. I should probably test this on STM32 receivers just to be sure, but ESP8285 seemed ok. Coming from config version 6 (ExpressLRS 3.1.x-3.2.x), the normal defaults are applied to all platforms as part of the upgrade process.

Feature Name

I've used TeamRce in the config, but I'm open to a more generic term for this model select feature. Jye came up with "Squad Select" which I ❤️ but I am afraid that is too long to fit in the Lua, TeamRce Pos is already the max length for B&W screens. Help? EDIT: After a few months of sitting on this I think the least obfuscated name is best. Call it what it is.

@JyeSmith
Copy link
Member

Nice one!

This is really useful for not only team racing but also practice session on your own, or at events.

Two consecutive packets are required to make the switch because in my testing a certain major brand transmitter was found to transmit intermediate values when switching between 6-pos positions.

ETX samples the adc 4 consecutive times and averages when the mixer fires. This might be due to the aux changing mid sampling and just affect all handsets???

It would be faaaaantastic if we could also put the VTX into Pit Mode or shut it down entirely but there are two challenges here:

Shouldnt be a problem to use a BF mode on the same aux to control the VTx. If a user can make it through setting up pinio then this should be a breeze 😅

Ive only skimmed through the changes but didnt see any control for the SPI VTx?

I've used TeamRce in the config, but I'm open to a more generic term for this model select feature. Jye came up with "Squad Select" which I ❤️ but I am afraid that is too long to fit in the Lua, TeamRce Pos is already the max length for B&W screens. Help?

Squad Aux
Fleet Ctrl

@CapnBry
Copy link
Member Author

CapnBry commented Apr 25, 2023

NOTE! This is apparently not ready for testing as it has a timing issue that lets a channels packets come through every 10-20 seconds. I'll get a fix in later today. Also MSP packets can still go and I didn't noticed that the device system has a modelmatch autoevent so I'll fix that and remove my manual event generation. EDIT: Fixed

Two consecutive packets are required to make the switch because in my testing a certain major brand transmitter was found to transmit intermediate values when switching between 6-pos positions.

ETX samples the adc 4 consecutive times and averages when the mixer fires. This might be due to the aux changing mid sampling and just affect all handsets???

Yeah it is likely due to a smoothing capacitor on the 6pos module output / ADC input that has a settling time. I could not reproduce it at all on my TX16S but it happened like once in every 2-3 changes on my other radio. It was still running the EdgeTX 2.8 firmware that came on it, so I updated and noticed that the 6pos (S3) was set to "Potentiometer". I set it to "Multipos" and recalibrated and haven't seen the issue since. Either way I still think it is a good idea to wait for 2 packets.

It would be faaaaantastic if we could also put the VTX into Pit Mode or shut it down entirely but there are two challenges here:

Ive only skimmed through the changes but didnt see any control for the SPI VTx?

I did not do any VTX stuff in this pass, was planning on adding that in the next PR with the MSP stuff as well. I don't have any SPI VTX ELRS hardware, I didn't even know it existed. Maybe I can get a sample (kissyface emoji)?

Regarding the name, I can make a folder for these items and then the name won't be restricted in length. It really slows down setting it because it reloads the entire top level every time you change the setting so that would make it faster by making the initial load slower 😅

@CapnBry CapnBry changed the title Add basic teamrace model select via channel Add basic teamrace model select via channel "Squad Select" Apr 27, 2023
@CapnBry
Copy link
Member Author

CapnBry commented May 9, 2023

Ah fuck me in the goat ass, STM32 target not enough flash now? Thanks a lot, Paul!

@pkendall64
Copy link
Collaborator

pkendall64 commented May 9, 2023

Ah fuck me in the goat ass, STM32 target not enough flash now? Thanks a lot, Paul!

Bro I was trying to help! I'm sure it was Jyes RS2 Pro which is just SBUS with fixes endpoints! 😅

@woutput
Copy link

woutput commented Jun 3, 2023

Great stuff!

Just another idea/scenario:

  1. Fly quad A one to some location
  2. Set quad A to GPS location and altitude hold*
  3. Fly quad B to some other location
  4. Set quad B to GPS location and altitude hold* (maybe filming quad A from a distance?)
  5. Have fun :)

* so not failsafe but just some autopilot mode

Thanks to at all @ ELRS for their work and great choice to go open source

@CapnBry
Copy link
Member Author

CapnBry commented Jun 5, 2023

Just another idea/scenario:

Hey, didn't I say right in the original post that this PR should NOT be used for this? Like, explicitly say not for "...launching a model and putting it into autopilot, then switching to a second model to chase it..." 😡 I'm not the King of FPV though, so I can't stop what people will do with it! /wanders off

I've flagged this as "Do Not Merge" as a merge conflict from master has got me all riled up. #2211 sort of took the "let the SerialIO class decide to send the channels or not" paradigm that had been established and changed it to, "well, sometimes some things you don't get to decide on" of which TeamRace should be included as well.

The SBUS IO class is a special snowflake that puts out channels at 9ms interval and has all its own special one-off logic, such as "failsafe" condition, which is different than "disconnected", which also has different rules than a PWM failsafe condition. It is making a mess of where the decision should be made and this needs further discussion.

Discussion

  • The failsafe logic should use the PWM failsafe logic and not just wait for "disconnected" state. We've already been through this: the disconnected state is FAR FAR FAR FAR FAR FAR FAR FAR FAR too long. Even the 1s timeout was too long. It should be changed to 0 LQ or 1s max with no updates
  • sendRCFrameToFC() prototype should maybe be expanded to pass the combination of ConnectionHasModelMatch && TeamRaceModelIsSelected && !failsafe, instead of just frameAvailable (changed to sendChannels in this PR) . Any of those could be considered "do not send data" although we need to discuss the difference between ModelMatch / TeamRace / Failsafe conditions with regard to SBUS connections. In master, something going to !ModelMatch will never send a failsafe flag to SBUS, and this also extends to !TeamRace. All of these should be supported properly and their interpretation must be consistent across protocols. Our shit's confusing enough without having special cases for every possible condition and every different protocol. 😅

@CapnBry CapnBry changed the title Add basic teamrace model select via channel "Squad Select" Add basic teamrace model select via channel Dec 13, 2023
@CapnBry
Copy link
Member Author

CapnBry commented Dec 13, 2023

As per my last message, I was planning to redo the failsafe system to unify it between Servos, CRSF, and SBUS implementations but I did not get to it and 3.4 is right around the corner. I've updated the code to current with the still-split failsafe implementation to make this easy to review and I can just do that for 3.5.

@CapnBry CapnBry added enhancement 🪄 New feature or request and removed do not merge 🚫 labels Dec 13, 2023
src/src/rx-serial/devSerialIO.cpp Show resolved Hide resolved
src/lib/CrsfProtocol/crsf_protocol.h Outdated Show resolved Hide resolved
src/src/rx-serial/devSerialIO.cpp Show resolved Hide resolved
Copy link
Collaborator

@pkendall64 pkendall64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did a whole bunch of testing with this today. Once I got my 6P switch working (somehow it was gone from EdgeTX) it was fairly simple to get working.

It might be nice to also have this information available in the web UI at some stage too.

@pkendall64
Copy link
Collaborator

Oh, and BTW we're going to need a very nice CapnBry video on how to set this up for people.

src/lib/DEVICE/device.cpp Outdated Show resolved Hide resolved
Copy link
Collaborator

@wvarty wvarty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly looks ok other than a few very minor suggestions

Copy link
Collaborator

@pkendall64 pkendall64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You get another approval!

@CapnBry CapnBry merged commit f6de862 into ExpressLRS:master Mar 21, 2024
43 checks passed
@wimalopaan
Copy link

Would be cool to have a CRSF-command to switch the active receiver. This is not to "waste" one of the 16 rc-channels for that switching purpose. The drawback would be, that one as to use a LUA-script on the handset to issue the CRSF command via crsfTelemetryPush().

@wimalopaan
Copy link

wimalopaan commented Apr 24, 2024

Another cool option would be to have the "disabled" receivers still output the channel data. Well, you call it dangerous, but in the ship/boat-modelists scene, it it not uncommon to have many models at the same time active. And it would be really cool to see all the telemetry of all models simply be selecting the model.

Following the discussion here: https://discord.com/channels/839849772864503828/839856795781431317/1231278199720378439

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement 🪄 New feature or request V3.4 🍟
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants