I would like to know if it is possible to change the current camera display programmatically. What I would like to achieve as the end result is having two cameras, one forward, one backward, that switch based on the direction the robot is currently moving (with a manual override).
I currently am able to manually change the view by selecting the desired view from the drop-down menu on the dashboard, and may display both simultaneously if I wish.
You can do something like this (edited from the screenstepspage):
public void robotInit() {
new Thread(() -> {
UsbCamera camera1 = CameraServer.getInstance().startAutomaticCapture(0);
camera1.setResolution(640, 480);
UsbCamera camera2 = CameraServer.getInstance().startAutomaticCapture(1);
camera2.setResolution(640, 480);
CvSink cvSink1 = CameraServer.getInstance().getVideo(camera1);
CvSink cvSink2 = CameraServer.getInstance().getVideo(camera2);
CvSource outputStream = CameraServer.getInstance().putVideo("Switcher", 640, 480);
Mat image = new Mat();
while(!Thread.interrupted()) {
if(/*switcher button logic*/){
cvSink1.grabFrame(image);
} else{
cvSink2.grabFrame(image);
}
outputStream.putFrame(image);
}
}).start();
}
I’m tired, so this is all I can think of now. The code may not be entirely right, but the general idea should work. There probably is a much better/simpler/more efficient way that I have no clue about.
The above code gets you about 90% of the way their, but still runs into USB bandwidth issues. I modified the code slightly and now have switching cameras working very well, with the occasional error message, but nothing fatal.
public void robotInit() {
Thread t = new Thread(() -> {
boolean allowCam1 = false;
UsbCamera camera1 = CameraServer.getInstance().startAutomaticCapture(0);
camera1.setResolution(320, 240);
camera1.setFPS(30);
UsbCamera camera2 = CameraServer.getInstance().startAutomaticCapture(1);
camera2.setResolution(320, 240);
camera2.setFPS(30);
CvSink cvSink1 = CameraServer.getInstance().getVideo(camera1);
CvSink cvSink2 = CameraServer.getInstance().getVideo(camera2);
CvSource outputStream = CameraServer.getInstance().putVideo("Switcher", 320, 240);
Mat image = new Mat();
while(!Thread.interrupted()) {
if(oi.getGamepad().getRawButton(9)) {
allowCam1 = !allowCam1;
}
if(allowCam1){
cvSink2.setEnabled(false);
cvSink1.setEnabled(true);
cvSink1.grabFrame(image);
} else{
cvSink1.setEnabled(false);
cvSink2.setEnabled(true);
cvSink2.grabFrame(image);
}
outputStream.putFrame(image);
}
});
t.start();
When I attempt to add the switcher, I get a large number of errors and warnings. Something like unable to set FPS or unable to set resolution. It’s really irritating, the errors go away when I comment out the switching code, but the dashboard still shows >30 FPS for both cameras, and higher resolution (even though my code sets the resolution and FPS lower).
I am using two Lifecam 3000s if it matters.
On the dashboard are you streaming the Switcher? If you try to stream just the default USB cameras, you will get errors.