-
Notifications
You must be signed in to change notification settings - Fork 3.2k
I2C inefficiency caused by the use of read windows with REV Expansion Hubs #542
Comments
I'd like to see you repeat your benchmark using firmware 1.8.2. |
I would, but unfortunately I no longer have access to a hub for testing. It'd be great if others could reproduce my initial results with 3.x/1.7.2 and see how much has changed in 4.x/1.8.2. Given that |
It appears that this issue is still present with 4.x/1.8.2. Here are the results for a similar benchmark measuring IMU Euler angle reads (i.e., Here is the benchmark code. |
Thanks for refreshing this post. Although I only use the one internal I2C device, our latencies are going up, so I'll be interested to see the impact of this tweak. Have your studies shown any other methods for reducing cycle times? |
The main other trick is bulk input reads. This feature exists in the current SDK although you have to use the command directly ( Unfortunately, there's no equivalent for bulk writes (aside from I also recommend that teams have a separate thread purely for hardware commands to ensure maximum utilization of the bus. Finally, if you're very adventurous, you could remove the USB-level lock and replace it with a hub-level lock (as suggested by this comment) and theoretically send commands concurrently with a two-hub configuration. |
Great info... thanks. |
But, that would require that both Hubs be connected via USB, though. (Which is allowed according to GDC btw) |
I've implemented both the faster I2C (for my IMU only) and bulk reads for my 6 encoders. This is a pretty respectable improvement, especially when the loop time bounces up. Thanks for the research and libs guys. |
@gearsincorg you could get that loop time down even further if REV implements bulk I2C reads (some pulling apart of the Hub interface software indicates that may be a future feature) and/or bulk writes. The fact of the matter is, every command takes about 3ms to send over the bus and then have an ack come back. So every hardware call you make adds a minimum of 3ms to your loop time. |
Could someone lay out how to implement these improvements to someone who doesn't understand the internal working of the SDK? Our robot has 8 motors, 7 with encoders, so speeding up reading encoder values could be quite useful for our TeleOp and Auto. |
@qwertychouskie check out the bulk data example OpMode in RevExtensions2 |
@FROGbots-4634 Is the |
@qwertychouskie heh, that thought never even crossed my mind when I was writing the library, lol. Well, by taking a look at LynxDcMotorController it seems that |
Fixed in v5.3 |
The implementation of
I2cDeviceSynchImplOnSimple
used to wrapLynxI2cDeviceSynch
instances for all REV I2C devices will read extra registers according to the read window that are never used. This isn't really problematic except that the duration of I2C read commands are linear, not constant in the number of registers.By bypassing the read window, one can achieve fairly significant speedups. In particular, here is the difference between an unoptimized and optimized (read window-less) BNO055 Euler angle read:
(This was generated using https://github.com/acmerobotics/relic-recovery/blob/master/TeamCode/src/main/java/com/acmerobotics/relicrecovery/opmodes/test/ExpansionHubBenchmark.java)
To remedy this, one can subclass
I2cDeviceSynchImplOnSimple
and use it to constructI2cDeviceSynch
instances without read windows:The text was updated successfully, but these errors were encountered: