FIRST-Tech-Challenge / SkyStone

FTC SDK
https://www.firstinspires.org/robotics/ftc/what-is-first-tech-challenge
275 stars 1.04k forks source link

Multiple cameras with Vuforia using SwitchableCamera #203

Open Milotrince opened 4 years ago

Milotrince commented 4 years ago

Initializing Vuforia twice with different cameras always throws a no-camera-access error. But after looking through the sdk code (specifically VuforiaLocalizerImpl) I found that SwitchableCamera was a thing. It seems to suggest that running Vuforia on two separate cameras is possible by switching between them. What is the correct way to do this?

Setup: Control Hub with 2 web cameras connected. Both work when run individually.

Here is how I am using SwitchableCamera

CameraName webcam1 = hardwareMap.get(WebcamName.class, "webcam 1");
CameraName webcam2 = hardwareMap.get(WebcamName.class, "webcam 2");
SwitchableCameraName switchableCameraName = SwitchableCameraNameImpl.forSwitchable(webcam1, webcam2);

VuforiaLocalizer.Parameters parameters = new VuforiaLocalizer.Parameters();
parameters.cameraName = switchableCameraName; 

// ...and then the rest of vuforia initialization

I believe that Impl classes are not really meant to be used directly, but I could not find another way to create SwitchableCameraName.

When running this in an OpMode, I do not get any readings (trackables are not visible), and calling setActiveCameraon (SwitchableCamera) vuforiaLocalizer.getCamera() throws errors.

I will post the models of the webcams, the code I am using, and the specific error messages in a day or two once I go to the workshop again.

NoahAndrews commented 4 years ago

I'm not very familiar with that part of the codebase, but have you tried calling setActiveCamera() on switchableCameraName?

cmacfarl commented 4 years ago

Setup is effectively...

    SwitchableCamera switchableCamera;

    WebcamName webcam, webcam2;

    @Override public void runOpMode() {

        webcam = hardwareMap.get(WebcamName.class, "Webcam 1");
        webcam2 = hardwareMap.get(WebcamName.class, "Webcam 2");

        SwitchableCameraName switchableName = ClassFactory.getInstance().getCameraManager().nameForSwitchableCamera(webcam, webcam2);

        int cameraMonitorViewId = hardwareMap.appContext.getResources().getIdentifier("cameraMonitorViewId", "id", hardwareMap.appContext.getPackageName());
        VuforiaLocalizer.Parameters parameters = new VuforiaLocalizer.Parameters(cameraMonitorViewId);
        parameters.vuforiaLicenseKey = "AXcvdAD/////AAADmeAgjY5Fe0yHvh72y9/lFm8S1V6le6...RCeHLl5sz7+5+4csLJixo4irUhe27YvRDSfshvcjz0jIsne+YL";

        parameters.cameraName = switchableName;
        this.vuforia = ClassFactory.getInstance().createVuforia(parameters);
        this.switchableCamera = (SwitchableCamera)vuforia.getCamera();

        ... 

You can then switch cameras as so...

    void toggleCamera() {
        if (switchableCamera != null) {
            if (switchableCamera.getActiveCamera().equals(webcam)) {
                RobotLog.v("switching to camera#2: %s", webcam2);
                switchableCamera.setActiveCamera(webcam2);
            } else {
                RobotLog.v("switching to camera#1: %s", webcam);
                switchableCamera.setActiveCamera(webcam);
            }
        }
    }
Milotrince commented 4 years ago

setActiveCamera seems a bit finicky when I run it. I modified the webcam vuforia sample implementing the code @cmacfarl posted, but I've been getting mixed results. Sometimes the output is black after switching camera (using init -> Camera Stream), or I get an unable to start streaming error thrown from SwitchableCameraImpl. After this happens, both webcams no longer light up. Expected behavior is that the camera that is currently active has its light on.

switchablecameraerror.txt

The webcam models I am using are c920s and c110. They have different stream resolutions, 1080p and 720p. I read in the source code that SwitchableCamera works best when the cameras are of the same model. Would getting another model fix my issue?

Windwoes commented 4 years ago

You might be running into bandwidth issues. Have a look at this issue that was filed for EasyOpenCV https://github.com/OpenFTC/EasyOpenCV/issues/6