For the past day or two, any attempts to set the manual exposure for a USB camera using cscore has resulted in the error CS: ERROR: ioctl VIDIOC_S_EXT_CTRLS failed at UsbCameraProperty.cpp:67: Invalid argument (UsbUtil.cpp:156) and the exposure not getting updated. By default the camera is stuck in “auto exposure” mode, and ends up streaming at 7.5 fps, sometimes 15 if it is in the correct lighting conditions (it should be at 30).
Context:
Using wpilibpi w/ wpilib v2023.4.1 on a raspberry pi 4
Camera: Lifecam hd3000
This is a recent development; changing the exposure was working flawlessly before this error started occurring
What I have tried (nothing has worked):
Change the default exposure in the web dashboard for the camera
Change resolution and fps in the web dashboard for the camera
Plug the camera into a different USB port
Try the default ‘multiCameraServer’ program instead of our vision application
I have not tried reimaging yet, but can if absolutely necessary. Also, I briefly remember running a sudo apt update to install some debugging tools sometime before the errors started occurring, but did not run into the error for at least a day afterward simply because I didn’t retest the code during that time. I have been trying to figure out how to view the update history but have gotten nowhere. Could it be that the camera driver or some other dependency was updated and is now incompatible with cscore? If this was the case, I’m assuming a reimage would be necessary.
Does it work to set the exposure settings interactively on the stream server web page? E.g. set exposure to manual mode, and then move the manual mode slider?
The exact V4L2 property names for camera exposure seem to have changed over recent Linux kernel versions, and the SetExposureManual() function assumes certain names, so it’s relatively fragile right now. v4l2-ctl -D 0 --list-ctrls (or something similar to that) should list all the camera property names. You can use these names with GetProperty() to set specific properties like you can on the web page.
Setting the exposure manually on the stream web page also failed and produced the same output, except for half of the time when setting the raw exposure to 0 would work.
It is a Microsoft Lifecam HD3000 - here is the control mode list from the command you gave:
I wouldn’t know if any of them have changed, but I can try implementing the direct property modification and see if that works. As a side note, I always wondered how the stream gui had so many options while the api didn’t mention hardly any of them - I guess now I know.
Yep, those names are not what the code assumes for those properties. The code assumes exposure_auto and exposure_absolute (instead of auto_exposure and exposure_time_absolute). Linux changed the names at some point relatively recently. Note for setting exposure_time_absolute you’ll want to implement this scaling function to go from the 0-100 range to the exact values required by the LifeCam (or just use one of the exact values, since you’re setting a fixed value anyway): allwpilib/UsbCameraImpl.cpp at main · wpilibsuite/allwpilib · GitHub
(the weird LifeCam exposure range is why setting the exposure through the web gui doesn’t work… and why we provide a dedicated function for it)
but it is still stuck in auto exposure mode unless the value being set is 0 (then it sets to a very low exposure). No error outputs except for at initialization where I presume other parameters that also had their id names changed are failing.
I tried manually sending values from the lookup table (5, 20, 156, etc.), but nothing happened. This is the same behavior I was seeing when setting from the web gui.
You need to set auto_exposure to 0 to get manual exposure control via exposure_time_absolute. Setting it to 1 is enabling auto exposure, disabling manual exposure control. You can confirm the menu values with v4l2-ctl, but I’m near-certain setting it to 0 is what you need to do.
1 is correct.
In the source code (UsbCameraImpl.cpp:1493), it is being set to 1 before manual setting, and I tried setting it to 0 and it spit out the same “invalid property” error.
…I was about to ask how to confirm the menu values but I figured it out: