Microsoft USB Camera Error

We are trying to use a Microsoft Lifecam HD-3000 as a usb camera through the roborio. We have been using the code from the simple vision example:

CameraServer::GetInstance()->SetQuality(50);
CameraServer::GetInstance()->StartAutomaticCapture(“cam0”);

However, once we start the driver station we get this error:

at /opt/GenICam_v2_3/bin/Linux_armv7-a/libstdc++.so.6(+0xa2cb0) [0xb5e77cb0]Error on line 207 Incompatible State: The operation cannot be completed: Choose “USB Camera HW” on the dashboard
at CameraServer::Serve()

We have eventually gotten the camera feed to show up in java dashboard, but only after creating a couple of different camera objects and then restarting the dashboard. Otherwise it just comes up as connection reset or robot has stopped returning images. Any advice?

We debugged this problem (we had it too) and discovered that it’s because CameraServer expects all client information to arrive in one packet. The dashboard sends it in 2 packets, so CameraServer thinks part of the information is missing. You can find our fix for this here.

Thanks, a little bit confused on where to put the code though. Does it go inside of a header file?

Hey, same problem, appreciate the solution. Where is this file to fix it?

FYI, this seems to be a known error:
https://usfirst.collab.net/sf/go/artf4015?nav=1&_pagenum=1&returnUrlKey=1454974655331

When using the USB Cameras I would suggest not doing automatic capture. The following is something I made that works. This code is for toggling between two USB cameras, because we have a front and back cam.

CPP File:

/*
 * LHSVision.cpp
 *
 *  Created on: Jan 26, 2016
 *      Author: Michael Conard
 *
 *  THING TO CHECK:
 *  	-In Internet Explorer, roborio-4237-frc.local,
 *  	 confirm the camera names in Silverlight. These
 *  	 should be "cam0", "cam1", or "cam2".
 *
 *  	-These names can be adjusted in the CAMERA
 *  	 namespace.
 */

#include "WPILib.h"
#include "LHSVision.h"

namespace XBOX		//Joystick Constants
{
	const int NODE_ID = 1;

	const int XBOX_A_BUTTON  = 1;
	const int XBOX_X_BUTTON = 3;

	const int XBOX_LEFT_X = 0;
	const int XBOX_LEFT_Y = 1;
}

namespace CAMERA	//Camera Names
{
	const char* CAM_ONE = "cam1";
	const char* CAM_TWO = "cam2";
}

//NOTE: Camera 1 is the default camera. Can toggle to 2 later.
LHSVision::LHSVision(RobotDrive* pRobot, Joystick* pXbox) //Constructor
{
	printf("File %18s Date %s Time %s Object %p
",__FILE__,__DATE__, __TIME__, this);

	frame = imaqCreateImage(IMAQ_IMAGE_RGB, 0);
	IMAQdxOpenCamera(CAMERA::CAM_ONE, IMAQdxCameraControlModeController, &session);
	Wait(.5);
	IMAQdxConfigureGrab(session);
	Wait(.5);
	IMAQdxStartAcquisition(session);
	Wait(.5);

	frame2 = imaqCreateImage(IMAQ_IMAGE_RGB, 0);

	mRobot = pRobot;
	mXbox = pXbox;
}

LHSVision::~LHSVision() //Destructor
{
	delete mXbox;
	delete mRobot;
}

//Used for closing and stopping acquisition of a camera
void LHSVision::StopCamera(int camNum)
{
	if(camNum == 1)	//Camera 1 Shutdown
	{
		IMAQdxStopAcquisition(session);
		Wait(.01);
		IMAQdxCloseCamera(session);
	}
	else			//Camera 2 Shutdown
	{
		IMAQdxStopAcquisition(session2);
		Wait(.01);
		IMAQdxCloseCamera(session2);
	}
}

//Used for opening, configuring, and starting acquisition of a camera
void LHSVision::StartCamera(int camNum)
{
	if(camNum == 1) //Camera 1 Startup
	{
		IMAQdxOpenCamera(CAMERA::CAM_ONE, IMAQdxCameraControlModeController, &session);
		Wait(.01);
		IMAQdxConfigureGrab(session);
		Wait(.01);
		IMAQdxStartAcquisition(session);
		Wait(.01);
	}
	else			//Camera 2 Startup
	{
		IMAQdxOpenCamera(CAMERA::CAM_TWO, IMAQdxCameraControlModeController, &session2);
		Wait(.01);
		IMAQdxConfigureGrab(session2);
		Wait(.01);
		IMAQdxStartAcquisition(session2);
		Wait(.01);
	}
}

//Send image to FRC PC Dashboard
void LHSVision::SendToDashboard(Image *image)
{
	CameraServer::GetInstance()->SetImage(image);
}

void LHSVision::UpdateVision() //by Michael
{
	if(mXbox->GetRawButton(XBOX::XBOX_A_BUTTON) == true)	//Toggle on A button press
	{
		while(mXbox->GetRawButton(XBOX::XBOX_A_BUTTON) == true)	//Prevents multi-press
		{}
		if(send == 1)
		{
			StopCamera(1);	//Stop Cam 1
			StartCamera(2);	//Start Cam 2
			printf("
Activating Camera 2 - Raw Image Display

");
			send = 2;
		}
		else
		{
			StopCamera(2);	//Stop Cam 2
			StartCamera(1);	//Start Cam 1
			printf("
Activating Camera 1 - Raw Image Display

");
			send = 1;
		}
	}

	if(send == 1)
	{
		IMAQdxGrab(session, frame, true, NULL);
		SendToDashboard(frame);		//Send Cam 1
		Wait(.1);
	}
	else
	{
		IMAQdxGrab(session2, frame2, true, NULL);
		SendToDashboard(frame2);	//Send Cam 2
		Wait(.1);
	}
}

Header File:

/*
 * LHSVision.h
 *
 *  Created on: Jan 25, 2016
 *      Author: Michael Conard
 */

#ifndef LHS_VISION_H
#define LHS_VISION_H

class RobotDrive;
class Joystick;

class LHSVision
{
public:
	LHSVision(RobotDrive*, Joystick*); //Constructor
	~LHSVision();	//Destructor
	void SendToDashboard(Image*); //Send Image to Dashboard
	void UpdateVision();	//Toggle and Display Camera
	void StopCamera(int);	//Close Specified Camera
	void StartCamera(int);	//Start Specified Camera

private:
	IMAQdxSession session;
	Image* frame;

	IMAQdxSession session2;
	Image* frame2;

	RobotDrive* mRobot;
	Joystick* mXbox;

	int send = 1;
};

#endif

My Main File:

/*
 * Robot.cpp
 *
 *  Created on: Jan 25, 2016
 *      Author: Michael Conard
 *
 *  This program requires:
 *  		-XBox Joystick
 *  		-Left Drive Talon
 *  		-Right Drive Talon
 *  		-Two USB Cameras on Roborio
 *  Ports can be adjusted below in PORTS namespace.
 *
 *  Controls:
 *  	-Forward/Reverse, Left Y Axis
 *  	-Rotating/Spinning, Left X Axis
 *  	-Toggling Front/Back Camera, A Button
 *
 *  Info: The cameras display to the FRC PC Dashboard.
 * 		  To open this: FRC Driver Station -> Third
 * 		  Tab (Setup) -> Set "Dashboard Type" to "Default"
 *
 * 		  In the FRC PC Dashboard near the bottom-middle,
 * 		  change "Camera Off" to "USB Camera HW".
 */

#include "WPILib.h"
#include "LHSVision.h"

namespace XBOX	//Joystick Constants
{
	const int NODE_ID = 1;

	const int XBOX_A_BUTTON  = 1;
	const int XBOX_X_BUTTON = 3;

	const int XBOX_LEFT_X = 0;
	const int XBOX_LEFT_Y = 1;
}

namespace PORTS	//Motor Constants
{
	const int LEFT_MOTOR = 0;
	const int RIGHT_MOTOR = 1;
}

class Robot: public SampleRobot
{
private:
	RobotDrive* mRobot;		//RobotDrive with two Talons
	Joystick* mStick;		//Joystick
	LHSVision* mLHSVision;	//Raw Image Display
public:
	Robot();				//Constructor
	~Robot();				//Destructor
	void OperatorControl();	//Can Drive and Toggle Cameras
	void Autonomous();		//No Content
};

Robot::Robot()	//Constructor
{
	printf("File %18s Date %s Time %s Object %p
",__FILE__,__DATE__, __TIME__, this);

	mRobot = new RobotDrive(PORTS::LEFT_MOTOR, PORTS::RIGHT_MOTOR);
	mStick = new Joystick(XBOX::NODE_ID);
	mLHSVision = new LHSVision(mRobot, mStick);	//LHSVision requires a RobotDrive and Joystick
}

Robot::~Robot()	//Destructor
{
	delete mRobot;
	delete mStick;
}

void Robot::OperatorControl()	//Driving and Camera Toggling
{
	while(IsOperatorControl() && IsEnabled())
	{
		mRobot->ArcadeDrive(mStick->GetRawAxis(XBOX::XBOX_LEFT_Y), mStick->GetRawAxis(XBOX::XBOX_LEFT_X));

		mLHSVision->UpdateVision();
		Wait(0.02);
	}
}

void Robot::Autonomous()	//No Content
{
	while(IsAutonomous() && IsEnabled())
	{
		printf("Autonomous!
");
	}
}

START_ROBOT_CLASS(Robot)

I hope this helps. If you need me to simplify my code structure to do only one USB camera let me know.

Put LCameraServer.cpp and LCameraServer.h in your project, and then use the LCameraServer class as you would CameraServer. Don’t use both at the same time (of course).

I would also recommend not using automatic capture. Grab your images using IMAQdx and call SetImage directly.