add auto gain

This commit is contained in:
yair 2025-11-16 04:05:26 +02:00
parent 6654b99eab
commit 43878b36e2
4 changed files with 108 additions and 12 deletions

View File

@ -17,6 +17,8 @@ Usage:
uv run scripts/camera_control.py set-gain 50 # Set gain to 50 uv run scripts/camera_control.py set-gain 50 # Set gain to 50
uv run scripts/camera_control.py get-auto-exposure # Get auto-exposure status uv run scripts/camera_control.py get-auto-exposure # Get auto-exposure status
uv run scripts/camera_control.py set-auto-exposure 1 # Enable auto-exposure uv run scripts/camera_control.py set-auto-exposure 1 # Enable auto-exposure
uv run scripts/camera_control.py get-auto-gain # Get auto-gain status
uv run scripts/camera_control.py set-auto-gain 1 # Enable auto-gain
uv run scripts/camera_control.py status # Get pipeline status uv run scripts/camera_control.py status # Get pipeline status
This script provides both individual control commands and full test suite functionality This script provides both individual control commands and full test suite functionality
@ -186,6 +188,8 @@ Examples:
%(prog)s set-gain 50 # Set gain to 50 %(prog)s set-gain 50 # Set gain to 50
%(prog)s get-auto-exposure # Get auto-exposure status %(prog)s get-auto-exposure # Get auto-exposure status
%(prog)s set-auto-exposure 1 # Enable auto-exposure %(prog)s set-auto-exposure 1 # Enable auto-exposure
%(prog)s get-auto-gain # Get auto-gain status
%(prog)s set-auto-gain 1 # Enable auto-gain
%(prog)s status # Get pipeline status %(prog)s status # Get pipeline status
""", """,
formatter_class=argparse.RawDescriptionHelpFormatter formatter_class=argparse.RawDescriptionHelpFormatter
@ -194,7 +198,8 @@ Examples:
parser.add_argument('command', parser.add_argument('command',
nargs='?', nargs='?',
choices=['test', 'get-exposure', 'set-exposure', 'get-framerate', 'set-framerate', choices=['test', 'get-exposure', 'set-exposure', 'get-framerate', 'set-framerate',
'get-gain', 'set-gain', 'get-auto-exposure', 'set-auto-exposure', 'status'], 'get-gain', 'set-gain', 'get-auto-exposure', 'set-auto-exposure',
'get-auto-gain', 'set-auto-gain', 'status'],
help='Command to execute') help='Command to execute')
parser.add_argument('value', parser.add_argument('value',
@ -279,6 +284,22 @@ Examples:
success = simple_command(f"SET_AUTO_EXPOSURE {ae_value}", success = simple_command(f"SET_AUTO_EXPOSURE {ae_value}",
f"{'Enabling' if ae_value else 'Disabling'} auto-exposure") f"{'Enabling' if ae_value else 'Disabling'} auto-exposure")
elif args.command == 'get-auto-gain':
success = simple_command("GET_AUTO_GAIN", "Getting auto-gain status")
elif args.command == 'set-auto-gain':
if args.value is None:
print("Error: set-auto-gain requires a value (0=off, 1=on)")
parser.print_help()
sys.exit(1)
# Convert to int
ag_value = int(args.value)
if ag_value not in [0, 1]:
print("Error: Auto-gain must be 0 (off) or 1 (on)")
sys.exit(1)
success = simple_command(f"SET_AUTO_GAIN {ag_value}",
f"{'Enabling' if ag_value else 'Disabling'} auto-gain")
elif args.command == 'status': elif args.command == 'status':
success = simple_command("STATUS", "Getting pipeline status") success = simple_command("STATUS", "Getting pipeline status")

View File

@ -28,7 +28,8 @@
# - Dynamic exposure control (0.015-30000 milliseconds, default: 10ms) # - Dynamic exposure control (0.015-30000 milliseconds, default: 10ms)
# - Auto-exposure mode support (--auto-exposure flag) # - Auto-exposure mode support (--auto-exposure flag)
# - Dynamic framerate control (1-20000 fps, default: 750fps) # - Dynamic framerate control (1-20000 fps, default: 750fps)
# - Dynamic gain control (0-100, 0 for auto, default: 0) # - Dynamic gain control (0-100, default: 0)
# - Auto-gain mode support (--auto-gain flag)
# - Dynamic camera ID selection (0-254, default: 0 for first found) # - Dynamic camera ID selection (0-254, default: 0 for first found)
# - Dynamic device ID selection (0-254, system enumeration ID) # - Dynamic device ID selection (0-254, system enumeration ID)
# - Configurable video cropping (default: crop 3 pixels from bottom) # - Configurable video cropping (default: crop 3 pixels from bottom)
@ -44,10 +45,12 @@
# GET_CAMERA_ID - Get current camera ID # GET_CAMERA_ID - Get current camera ID
# SET_DEVICE_ID <value> - Set device ID (0-254, system enumeration) # SET_DEVICE_ID <value> - Set device ID (0-254, system enumeration)
# GET_DEVICE_ID - Get current device ID # GET_DEVICE_ID - Get current device ID
# SET_GAIN <value> - Set master gain (0-100, 0 for auto) # SET_GAIN <value> - Set master gain (0-100)
# GET_GAIN - Get current gain value # GET_GAIN - Get current gain value
# SET_AUTO_EXPOSURE <0|1> - Enable (1) or disable (0) auto-exposure # SET_AUTO_EXPOSURE <0|1> - Enable (1) or disable (0) auto-exposure
# GET_AUTO_EXPOSURE - Get auto-exposure status # GET_AUTO_EXPOSURE - Get auto-exposure status
# SET_AUTO_GAIN <0|1> - Enable (1) or disable (0) auto-gain
# GET_AUTO_GAIN - Get auto-gain status
# STATUS - Get pipeline status and current settings # STATUS - Get pipeline status and current settings
# #
# Example Control Usage: # Example Control Usage:
@ -138,7 +141,8 @@ class ControlServer:
print(f"Control server listening on UDP port {self.port}") print(f"Control server listening on UDP port {self.port}")
print(" Commands: SET_EXPOSURE <val>, GET_EXPOSURE, SET_FRAMERATE <val>, GET_FRAMERATE,") print(" Commands: SET_EXPOSURE <val>, GET_EXPOSURE, SET_FRAMERATE <val>, GET_FRAMERATE,")
print(" SET_CAMERA_ID <val>, GET_CAMERA_ID, SET_DEVICE_ID <val>, GET_DEVICE_ID,") print(" SET_CAMERA_ID <val>, GET_CAMERA_ID, SET_DEVICE_ID <val>, GET_DEVICE_ID,")
print(" SET_GAIN <val>, GET_GAIN, SET_AUTO_EXPOSURE <0|1>, GET_AUTO_EXPOSURE, STATUS") print(" SET_GAIN <val>, GET_GAIN, SET_AUTO_EXPOSURE <0|1>, GET_AUTO_EXPOSURE,")
print(" SET_AUTO_GAIN <0|1>, GET_AUTO_GAIN, STATUS")
while self.running: while self.running:
try: try:
@ -200,6 +204,10 @@ class ControlServer:
return self.handle_set_auto_exposure(parts) return self.handle_set_auto_exposure(parts)
elif cmd == "GET_AUTO_EXPOSURE": elif cmd == "GET_AUTO_EXPOSURE":
return self.handle_get_auto_exposure() return self.handle_get_auto_exposure()
elif cmd == "SET_AUTO_GAIN":
return self.handle_set_auto_gain(parts)
elif cmd == "GET_AUTO_GAIN":
return self.handle_get_auto_gain()
elif cmd == "STATUS": elif cmd == "STATUS":
return self.handle_status() return self.handle_status()
else: else:
@ -371,6 +379,33 @@ class ControlServer:
except Exception as e: except Exception as e:
return f"ERROR: {str(e)}" return f"ERROR: {str(e)}"
def handle_set_auto_gain(self, parts):
"""Handle SET_AUTO_GAIN command"""
if len(parts) != 2:
return "ERROR INVALID_SYNTAX: Usage: SET_AUTO_GAIN <0|1>"
try:
value = int(parts[1])
if value not in [0, 1]:
return "ERROR OUT_OF_RANGE: Auto-gain must be 0 (off) or 1 (on)"
self.src.set_property("auto-gain", bool(value))
actual = self.src.get_property("auto-gain")
return f"OK {int(actual)}"
except ValueError:
return "ERROR INVALID_SYNTAX: Auto-gain must be 0 or 1"
except Exception as e:
return f"ERROR: {str(e)}"
def handle_get_auto_gain(self):
"""Handle GET_AUTO_GAIN command"""
try:
value = self.src.get_property("auto-gain")
return f"OK {int(value)}"
except Exception as e:
return f"ERROR: {str(e)}"
def handle_status(self): def handle_status(self):
"""Handle STATUS command""" """Handle STATUS command"""
try: try:
@ -380,6 +415,7 @@ class ControlServer:
device_id = self.src.get_property("device-id") device_id = self.src.get_property("device-id")
gain = self.src.get_property("gain") gain = self.src.get_property("gain")
auto_exposure = int(self.src.get_property("auto-exposure")) auto_exposure = int(self.src.get_property("auto-exposure"))
auto_gain = int(self.src.get_property("auto-gain"))
# Get pipeline state # Get pipeline state
state = "UNKNOWN" state = "UNKNOWN"
@ -387,7 +423,7 @@ class ControlServer:
_, current_state, _ = self.pipeline.get_state(0) _, current_state, _ = self.pipeline.get_state(0)
state = current_state.value_nick.upper() state = current_state.value_nick.upper()
return f"OK exposure={exposure} framerate={framerate} camera_id={camera_id} device_id={device_id} gain={gain} auto_exposure={auto_exposure} state={state}" return f"OK exposure={exposure} framerate={framerate} camera_id={camera_id} device_id={device_id} gain={gain} auto_exposure={auto_exposure} auto_gain={auto_gain} state={state}"
except Exception as e: except Exception as e:
return f"ERROR: {str(e)}" return f"ERROR: {str(e)}"

View File

@ -75,7 +75,8 @@ enum
PROP_EXPOSURE, PROP_EXPOSURE,
PROP_FRAMERATE, PROP_FRAMERATE,
PROP_GAIN, PROP_GAIN,
PROP_AUTO_EXPOSURE PROP_AUTO_EXPOSURE,
PROP_AUTO_GAIN
}; };
#define DEFAULT_PROP_CAMERA_ID 0 #define DEFAULT_PROP_CAMERA_ID 0
@ -87,6 +88,7 @@ enum
#define DEFAULT_PROP_FRAMERATE 0 #define DEFAULT_PROP_FRAMERATE 0
#define DEFAULT_PROP_GAIN 0 #define DEFAULT_PROP_GAIN 0
#define DEFAULT_PROP_AUTO_EXPOSURE FALSE #define DEFAULT_PROP_AUTO_EXPOSURE FALSE
#define DEFAULT_PROP_AUTO_GAIN FALSE
/* pad templates */ /* pad templates */
@ -175,6 +177,10 @@ gst_idsueyesrc_class_init (GstIdsueyeSrcClass * klass)
g_param_spec_boolean ("auto-exposure", "Auto Exposure", g_param_spec_boolean ("auto-exposure", "Auto Exposure",
"Enable automatic exposure control", DEFAULT_PROP_AUTO_EXPOSURE, "Enable automatic exposure control", DEFAULT_PROP_AUTO_EXPOSURE,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS))); (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
g_object_class_install_property (gobject_class, PROP_AUTO_GAIN,
g_param_spec_boolean ("auto-gain", "Auto Gain",
"Enable automatic gain control", DEFAULT_PROP_AUTO_GAIN,
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
} }
static void static void
@ -211,6 +217,7 @@ gst_idsueyesrc_init (GstIdsueyeSrc * src)
src->framerate = DEFAULT_PROP_FRAMERATE; src->framerate = DEFAULT_PROP_FRAMERATE;
src->gain = DEFAULT_PROP_GAIN; src->gain = DEFAULT_PROP_GAIN;
src->auto_exposure = DEFAULT_PROP_AUTO_EXPOSURE; src->auto_exposure = DEFAULT_PROP_AUTO_EXPOSURE;
src->auto_gain = DEFAULT_PROP_AUTO_GAIN;
src->stop_requested = FALSE; src->stop_requested = FALSE;
src->caps = NULL; src->caps = NULL;
@ -272,6 +279,12 @@ gst_idsueyesrc_set_property (GObject * object, guint property_id,
gst_idsueyesrc_set_framerate_exposure (src); gst_idsueyesrc_set_framerate_exposure (src);
} }
break; break;
case PROP_AUTO_GAIN:
src->auto_gain = g_value_get_boolean (value);
if (src->is_started) {
gst_idsueyesrc_set_framerate_exposure (src);
}
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; break;
@ -315,6 +328,9 @@ gst_idsueyesrc_get_property (GObject * object, guint property_id,
case PROP_AUTO_EXPOSURE: case PROP_AUTO_EXPOSURE:
g_value_set_boolean (value, src->auto_exposure); g_value_set_boolean (value, src->auto_exposure);
break; break;
case PROP_AUTO_GAIN:
g_value_set_boolean (value, src->auto_gain);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break; break;
@ -971,7 +987,28 @@ gst_idsueyesrc_set_framerate_exposure (GstIdsueyeSrc * src)
} }
} }
/* Set gain if specified (0 means use default/auto) */ /* Handle auto-gain */
if (src->auto_gain) {
/* Enable auto gain */
double enable = 1.0;
ret = is_SetAutoParameter (src->hCam, IS_SET_ENABLE_AUTO_GAIN,
&enable, NULL);
if (ret != IS_SUCCESS) {
GST_WARNING_OBJECT (src, "Failed to enable auto gain (error %d)", ret);
success = FALSE;
} else {
GST_DEBUG_OBJECT (src, "Auto gain enabled");
}
} else {
/* Disable auto gain */
double disable = 0.0;
ret = is_SetAutoParameter (src->hCam, IS_SET_ENABLE_AUTO_GAIN,
&disable, NULL);
if (ret != IS_SUCCESS) {
GST_WARNING_OBJECT (src, "Failed to disable auto gain (error %d)", ret);
}
/* Set manual gain if specified (0 means use default) */
if (src->gain > 0) { if (src->gain > 0) {
ret = is_SetHardwareGain (src->hCam, src->gain, IS_IGNORE_PARAMETER, ret = is_SetHardwareGain (src->hCam, src->gain, IS_IGNORE_PARAMETER,
IS_IGNORE_PARAMETER, IS_IGNORE_PARAMETER); IS_IGNORE_PARAMETER, IS_IGNORE_PARAMETER);
@ -981,6 +1018,7 @@ gst_idsueyesrc_set_framerate_exposure (GstIdsueyeSrc * src)
success = FALSE; success = FALSE;
} }
} }
}
return success; return success;
} }

View File

@ -59,6 +59,7 @@ struct _GstIdsueyeSrc
gdouble framerate; gdouble framerate;
gint gain; gint gain;
gboolean auto_exposure; gboolean auto_exposure;
gboolean auto_gain;
GstClockTime acq_start_time; GstClockTime acq_start_time;
guint32 last_frame_count; guint32 last_frame_count;