Ok, I took a deeper look into what you’re doing… Best I can tell, in Robot.java, which executes on the main thread (along with your drive commands and most, if not everything else) initializes RobotVisionDualUSB (Line 50 - and reinit on 87?). It also loops through and updates the images as well (lines 79, 102, 117).
The problem is, the image capture routine is slow, be it because it’s doing a lot of work, or some other reason, it’s just not fast. If you were to run those tasks on a separate thread it could be just as slow – but slow alongside the rest of your code that’s running at speed. (The RoboRIO is a dual-core processor, so it can run two threads simultaneously.)
I suggest you take a look at the WPILib code for CameraServer for some idea of what they are doing there. Starting at line 181, when you start capture you’ll see it create a new Thread in Java (line 189) that just captures images. That’s the only code that runs the capture() function (line 199) - which is where the images are loaded (line 200).
(If your head isn’t spinning yet – that WPILib code is a mess, read on. If you’re already lost, jump past this section.)
Granted we’re a rookie team, and I’m a rookie mentor, but… The WPILib CameraServer class does most of what we want, aside from handle multiple cameras, so why reinvent the wheel? Instead we took that CameraServer class and made a few modifications in DynamicCameraServer. (Code base is in major flux, hopefully that link will work for awhile.) All our changes are commented (Look for “// FRC5881 Mod”) and what we’ve done is to implement a way to tell the capture thread to stop, and a way to see that is has. Then we restart it with the new camera.
Most of the magic starts in the switchAutomaticCapture() function on line 209. Because the capture thread only runs when m_autoCaptureStarted is true (see line 251), we flip that to false, and wait for the next loop in capture() which ends and sets m_autoCaptureRunning to false. That in turn lets the switchAutomaticCapture() function (which has been sitting spinning and waiting for up to 1s - line 218 - which usually takes only about 30-40ms, may trigger a warning about motor updates… we’re working on this still) know it can close the old camera feed and start the new one and restart the capture() thread.
There are probably about a half-dozen better ways to do this and not block the main thread (like we do at 218) at all, but 30-40ms or so is a far better cry than what it was before. The other downside, that we might not be able to fix, is it does take about 1s-1.5s for the new video to start up on the driver station. Maybe it’s the close/open of the camera, maybe not.
(If your head was spinning before, start reading here)
The fundamental issue I think you have, first off, is you’re entire code is running on one single thread. Thus while you’re processing cameras, commands from the DS (move, turn, stop) aren’t being executed. What you need to look at is multithreaded operation and move video out of the main thread.
Hope this helps.