There are several places where there are “notify” events: e.g., motor fault notifications or color detection notifications. I assume these events are asynchronous…but how do they actually work? Do they just pop data in the output stream when they happen?
I’ve been building a C library for the RVR interface on a Raspberry Pi. For sensors, I spawn a separate thread to handle the sensor stream. But that works because the RVR will stream data until it’s told to stop. If the notify events push out data between other data outputs, it will require a different way to do it.
I’m going at it a little different. I have created a C# program with a form that has most of the functions broken out on it.
You can use the program to single step through the code and see how things are assembled and sent out to the RVR. I have also broken down the incoming stream data into the many parts.
Streaming seems a little confusing to me as there is not enough data coming back to identify what stream it is. So if you enable all the sensor streams it would be impossible to determine what sensor data you are getting back.
Any way I have a working C# program up on GitHub C# Form Project
Sensor streaming works by enabling a sensor and then telling it how often you want it to report back the data when you start it. The sensor data then comes back as a binary value that has to be scaled back to the actual sensor values.
The documentation only show 3 different values for token so that is not very useful if you want to stream Accelerometer and IMU with Gyro unless the token can be any value from 1 to 255 which is not clear from the documentation.
My testing shows the token values can be more than what is shown. Code base is under reorg so can’t check this in detail. But I used a token of 2 and a token of 7 for ambient light and the raw values were the same. Part of the reorg is how I calculate final value.
I was basing the token on the code in the control program. Just tried assigning tokens to each sensor and it works just fine. So multiple tokens can be used to identify different streams coming back from RVR.
My recent testing is having a problem with this. What I’m seeing is if I assign 4 tokens to the BluetoothSOC any additional tokens are rejected with an Error 6 - failed for command specific reason.
My interpretation now is there are 4 slots for tokens on each processor. The token itself can be any value within some limit but only 4 tokens can be active. The sensor table list tokens makes more sense now. I’ll probably organize differently, though.
Also pretty sure that only the lower nybble can be used. Had a token coming back with 0x1n because there was an error with the sensor. May have been the color detector because detection wasn’t enabled.
Sorry for the long delay in responding, I’ve been on vacation for a while. I haven’t worked on sensor streaming myself, but I’ll do my best to fill things in a bit for now, until we can publish more complete documentation.
You are correct that there are 4 slots. Each slot, termed a “configuration slot”, is basically a grouping of streaming services for a particular client (the client is outside of the robot). The tokens in the table you found in the docs are really only applicable to the SDK controls concept and the way the SDK groups sensors.
For doing it yourself, you can configure whatever sensors you want in a particular configuration slot, and each slot will send out a packet on the interval you specified. Streaming packets for individual configuration slots are evenly spaced during the streaming interval to reduce stackup of large packets, i.e. if you configure streaming at 500 ms with 2 slots, you’ll get a packet from one of the slots every 250 ms.
Correct, the token ID you provide is only the lower nibble of that byte in a streaming packet. The upper nibble contains status bits, and as you found, 0x1 means that at least one service could have a problem with its data. For example, you would get this if you configured color sensor streaming but didn’t enable color detection. 0x1 is currently the only implemented error bit.
I’m pushing to publish more thorough documentation of streaming, but don’t know when that will be ready.
I’ll file your findings in a ticket for the right person to look into it in more depth. The streaming module itself updates on a nominal 10 ms interval, which certainly makes even time division of 30ms/2 impossible, and perhaps rounding produces the 20 ms spacing from observation 2. I’m not sure about observation 3.
I’d suggest trying to just use one token for now if your system can handle receiving large packets. See if that makes things more predictable.