Log in

View Full Version : Microsoft USB Camera Error


csilent
04-02-2016, 09:16
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?

euhlmann
04-02-2016, 11:05
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 (https://github.com/ligerbots/Stronghold2016Robot/blob/master/src/Utils/LCameraServer.cpp#L191).

csilent
04-02-2016, 11:40
Thanks, a little bit confused on where to put the code though. Does it go inside of a header file?

kmckay
07-02-2016, 17:57
Hey, same problem, appreciate the solution. Where is this file to fix it?

kmckay
08-02-2016, 18:41
FYI, this seems to be a known error:
https://usfirst.collab.net/sf/go/artf4015?nav=1&_pagenum=1&returnUrlKey=1454974655331

MaikeruKonare
08-02-2016, 19:14
CameraServer::GetInstance()->StartAutomaticCapture("cam0");

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\n",__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("\nActivating Camera 2 - Raw Image Display\n\n");
send = 2;
}
else
{
StopCamera(2); //Stop Cam 2
StartCamera(1); //Start Cam 1
printf("\nActivating Camera 1 - Raw Image Display\n\n");
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\n",__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!\n");
}
}

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.

euhlmann
09-02-2016, 09:58
Thanks, a little bit confused on where to put the code though. Does it go inside of a header file?

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.