One of the inefficiencies in legacy `orb_subscribe()` addressed by the new `uORB…::Subscription` was that attempting to subscribe to a topic would create the underlying device node (the orb topic publication). As a result we had several kilobytes worth of unused orb device nodes in many setups.
In `uORB::Subscription` we avoid this by checking if the publication actually exists (equivalent to `orb_exists()`), however each `orb_exists()` call is relatively expensive. The short term optimization was to throttle the calls within `uORB::Subscription` after an initial 1000 attempts. The potential problem with this is a subscription might miss initial updates to topics that are only published late in flight.
This PR makes those orb existence checks cheap enough we can use them in every single iteration by adding a bitset of atomic integers to the uORB DeviceMaster. Then I updated the orb generation to also create a class enum for ORB_IDs so that we have an index to use with the bitset.
### Master (sensor_accel 0, 1, 2 exist, but 3 and 4 do not)
``` Console
orb_exists sensor_accel 0: 100 events, 983us elapsed, 9.83us avg, min 9us max 10us 0.377us rms
orb_exists sensor_accel 1: 100 events, 1424us elapsed, 14.24us avg, min 14us max 15us 0.429us rms
orb_exists sensor_accel 2: 100 events, 2031us elapsed, 20.31us avg, min 20us max 21us 0.464us rms
orb_exists sensor_accel 3: 100 events, 3373us elapsed, 33.73us avg, min 33us max 34us 0.446us rms
orb_exists sensor_accel 4: 100 events, 95us elapsed, 0.95us avg, min 1us max 1us 0.219us rms
```
### PR
``` Console
orb_exists sensor_accel 0: 100 events, 968us elapsed, 9.68us avg, min 9us max 10us 0.468us rms
orb_exists sensor_accel 1: 100 events, 1408us elapsed, 14.08us avg, min 14us max 15us 0.272us rms
orb_exists sensor_accel 2: 100 events, 2027us elapsed, 20.27us avg, min 20us max 21us 0.446us rms
orb_exists sensor_accel 3: 100 events, 161us elapsed, 1.61us avg, min 1us max 2us 0.490us rms
orb_exists sensor_accel 4: 100 events, 95us elapsed, 0.95us avg, min 1us max 1us 0.219us rms
orb_exists sensor_accel 5: 100 events, 89us elapsed, 0.89us avg, min 1us max 1us 0.314us rms
orb_exists sensor_accel 6: 100 events, 81us elapsed, 0.81us avg, min 1us max 1us 0.394us rms
orb_exists sensor_accel 7: 100 events, 90us elapsed, 0.90us avg, min 1us max 1us 0.301us rms
orb_exists sensor_accel 8: 100 events, 90us elapsed, 0.90us avg, min 0us max 1us 0.301us rms
orb_exists sensor_accel 9: 100 events, 91us elapsed, 0.91us avg, min 1us max 1us 0.287us rms
orb_exists sensor_accel 10: 100 events, 91us elapsed, 0.91us avg, min 0us max 1us 0.287us rms
```
In master `orb_exists()` for a topic that doesn't exist (with valid instance) is quite expensive because you have to search the entire list of topics. On fmu-v3 configured as a multicopter that's `33.73 us` (average). With this PR that same check is `1.61 us`. That might seem small, but it adds up across hundreds or even thousands of calls per second.
Overall this saves a little bit of cpu (although quite a lot during the first 5-10 seconds of bootup) and a little bit of memory, despite increasing the size of the orb_metadata struct. More importantly it removes the possibility of subtle unexpected orb update behavior later in flight.