gst-plugin-linescan/network_guide.md
yair d06a770aa4 docs: merge UDP control protocol and add script documentation to network guide
- Added documentation for launch-ids.py (Python-based camera control)
- Added documentation for test_exposure_control.py (UDP control testing)
- Added documentation for visualize_line_realtime.py (real-time visualization)
- Merged UDP_CONTROL_PROTOCOL.md content into network_guide.md
- Includes architecture diagrams, command reference, client examples
- Complete end-to-end guide for camera control and monitoring
2025-11-15 14:10:27 +02:00

15 KiB
Raw Blame History

How to Send a Single Line (2456x1)

Real Data - Single Line Transmission

The camera captures 2456x4 pixels, but we extract and transmit only one line (2456x1) using videocrop.

Daytime Configuration (200fps)

gst-launch-1.0 idsueyesrc config-file=ini/100fps-10exp-2456x4pix-500top-cw-extragain.ini exposure=0.05 framerate=200 `
    ! videocrop bottom=3 `
    ! queue `
    ! udpsink host=127.0.0.1 port=5000

Nighttime Configuration (100fps, extra gain)

gst-launch-1.0 idsueyesrc config-file=ini/100fps-10exp-2456x4pix-500top-cw-extragain.ini exposure=10 framerate=100 `
    ! videocrop bottom=3 `
    ! queue `
    ! udpsink host=127.0.0.1 port=5000

Key Parameters:

  • videocrop bottom=3 - Extracts only the top line (removes bottom 3 rows from 2456x4 image)
  • Input: 2456x4 BGR from camera
  • Output: 2456x1 BGR line transmitted via UDP
  • Frame size: 7368 bytes (2456 × 1 × 3 channels)

Alternative: To extract the bottom line instead, use videocrop top=3


Python-Based Control with Dynamic Parameter Adjustment

For more advanced control including runtime exposure and framerate adjustments, use the Python-based launcher with UDP control interface.

Launch Camera with Control Interface

See scripts/launch-ids.py for the complete implementation.

# Setup GStreamer environment and run
. .\scripts\setup_gstreamer_env.ps1
uv run .\scripts\launch-ids.py

Features:

  • Video streaming on UDP port 5000 (127.0.0.1)
  • Control interface on UDP port 5001 (0.0.0.0)
  • Dynamic exposure control (0.001-1.0 seconds)
  • Dynamic framerate control (1-500 fps)
  • Real-time parameter updates without restarting

Control Commands:

Command Description Example
SET_EXPOSURE <value> Set exposure in seconds SET_EXPOSURE 0.016
GET_EXPOSURE Get current exposure value GET_EXPOSURE
SET_FRAMERATE <value> Set framerate in Hz SET_FRAMERATE 30
GET_FRAMERATE Get current framerate GET_FRAMERATE
STATUS Get pipeline status and settings STATUS

Example Usage:

# Using netcat (nc) or PowerShell
echo "SET_EXPOSURE 0.010" | nc -u 127.0.0.1 5001
echo "GET_EXPOSURE" | nc -u 127.0.0.1 5001
echo "STATUS" | nc -u 127.0.0.1 5001

Testing the Control Interface

See scripts/test_exposure_control.py for automated testing.

# Run comprehensive test suite (15 tests)
uv run .\scripts\test_exposure_control.py

Test Coverage:

  • Get/Set exposure and framerate
  • Verify parameter changes take effect
  • Test input validation and error handling
  • Verify range limits (0.001-1.0s for exposure, 1-500 fps)
  • Test invalid commands and syntax

Example Test Output:

Test 1: Get current exposure
  Command:  GET_EXPOSURE
  Response: OK 0.016
  ✓ PASS

Test 2: Set exposure to 10ms
  Command:  SET_EXPOSURE 0.010
  Response: OK 0.01
  ✓ PASS

UDP Control Protocol Specification

Complete technical details for the UDP-based control interface.

Architecture

┌─────────────────────────────────────────────────────────────┐
│                     launch-ids.py Process                    │
├─────────────────────────────────────────────────────────────┤
│                                                               │
│  ┌──────────────────┐         ┌──────────────────────────┐  │
│  │   Main Thread    │         │  Control Server Thread   │  │
│  │                  │         │                          │  │
│  │  GStreamer       │◄────────┤  UDP Socket (Port 5001)  │  │
│  │  Pipeline        │ Thread- │  Command Parser          │  │
│  │  - idsueyesrc    │  Safe   │  Property Setter         │  │
│  │  - videocrop     │ Updates │  Response Handler        │  │
│  │  - queue         │         │                          │  │
│  │  - udpsink:5000  │         └──────────────────────────┘  │
│  └──────────────────┘                    ▲                   │
│                                           │                   │
└───────────────────────────────────────────┼───────────────────┘
                                            │
                                            │ UDP Commands
                                            │
                                   ┌────────┴────────┐
                                   │  Control Client │
                                   │  (Any UDP tool) │
                                   └─────────────────┘

Connection Details

  • Control Port: 5001 (UDP)
  • Bind Address: 0.0.0.0 (accepts from any interface)
  • Video Port: 5000 (UDP) - existing video stream, unchanged
  • Protocol: UDP (connectionless, stateless)
  • Encoding: ASCII text
  • Delimiter: Newline (\n)

Command Format

Commands follow this general structure:

COMMAND [PARAMETERS]\n

Commands are case-insensitive, but UPPERCASE is recommended for clarity.

Detailed Command Reference

1. SET_EXPOSURE

Description: Sets the camera exposure time.

Syntax:

SET_EXPOSURE <value>

Parameters:

  • <value>: Exposure time in seconds (float)
    • Range: 0.001 to 1.0 seconds (1ms to 1000ms)
    • Examples: 0.016 (16ms), 0.001 (1ms), 0.100 (100ms)

Response:

OK <actual_value>

or

ERROR <error_message>

Examples:

Client: SET_EXPOSURE 0.016\n
Server: OK 0.016\n

Client: SET_EXPOSURE 2.0\n
Server: ERROR OUT_OF_RANGE: Exposure must be 0.001-1.0 seconds\n

2. GET_EXPOSURE

Description: Retrieves the current exposure time.

Syntax:

GET_EXPOSURE

Parameters: None

Response:

OK <current_value>

Example:

Client: GET_EXPOSURE\n
Server: OK 0.016\n

3. SET_FRAMERATE

Description: Sets the camera frame rate.

Syntax:

SET_FRAMERATE <value>

Parameters:

  • <value>: Frame rate in Hz (float)
    • Range: 1.0 to 500.0 fps
    • Examples: 22, 30.5, 100

Response:

OK <actual_value>

or

ERROR <error_message>

Example:

Client: SET_FRAMERATE 30\n
Server: OK 30.0\n

4. GET_FRAMERATE

Description: Retrieves the current frame rate.

Syntax:

GET_FRAMERATE

Parameters: None

Response:

OK <current_value>

Example:

Client: GET_FRAMERATE\n
Server: OK 22.0\n

5. STATUS

Description: Get overall pipeline status and current settings.

Syntax:

STATUS

Parameters: None

Response:

OK exposure=<value> framerate=<value> state=<PLAYING|PAUSED|NULL>

Example:

Client: STATUS\n
Server: OK exposure=0.016 framerate=22.0 state=PLAYING\n

Error Handling

Error Response Format:

ERROR <error_code>: <error_message>

Common Error Codes:

Code Description Example
INVALID_COMMAND Unknown command ERROR INVALID_COMMAND: Unknown command 'FOO'
INVALID_SYNTAX Malformed command ERROR INVALID_SYNTAX: Missing parameter
OUT_OF_RANGE Value out of valid range ERROR OUT_OF_RANGE: Exposure must be 0.001-1.0
PROCESSING Internal processing error ERROR PROCESSING: Failed to set property

Client Implementation Examples

Python Client

import socket

def send_command(command, host="127.0.0.1", port=5001):
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.sendto(command.encode() + b'\n', (host, port))
    sock.settimeout(1.0)
    response, _ = sock.recvfrom(1024)
    sock.close()
    return response.decode().strip()

# Set exposure to 10ms
print(send_command("SET_EXPOSURE 0.010"))

# Get current exposure
print(send_command("GET_EXPOSURE"))

# Set framerate to 30fps
print(send_command("SET_FRAMERATE 30"))

Command Line (netcat/nc)

# Set exposure
echo "SET_EXPOSURE 0.020" | nc -u 127.0.0.1 5001

# Get exposure
echo "GET_EXPOSURE" | nc -u 127.0.0.1 5001

# Get status
echo "STATUS" | nc -u 127.0.0.1 5001

PowerShell Client

$udpClient = New-Object System.Net.Sockets.UdpClient
$endpoint = New-Object System.Net.IPEndPoint([System.Net.IPAddress]::Parse("127.0.0.1"), 5001)

# Send command
$bytes = [System.Text.Encoding]::ASCII.GetBytes("SET_EXPOSURE 0.015`n")
$udpClient.Send($bytes, $bytes.Length, $endpoint)

# Receive response
$udpClient.Client.ReceiveTimeout = 1000
$receiveBytes = $udpClient.Receive([ref]$endpoint)
$response = [System.Text.Encoding]::ASCII.GetString($receiveBytes)
Write-Host $response

$udpClient.Close()

Implementation Notes

Thread Safety

  • The control server runs in a separate daemon thread
  • GStreamer properties are inherently thread-safe (GObject properties)
  • The src.set_property() method can be safely called from the control thread

Non-Blocking Operation

  • Control server uses non-blocking socket with timeout
  • Does not interfere with GStreamer pipeline operation
  • Minimal latency for command processing

Response Timing

  • Responses are sent immediately after processing
  • Property changes take effect on the next frame capture
  • No guaranteed synchronization with video stream

Future Enhancements

Possible extensions to the protocol:

  • Add SET_GAIN / GET_GAIN commands
  • Add SAVE_CONFIG to save current settings to INI file
  • Add RESET to restore default settings
  • Support batch commands (multiple commands in one packet)
  • Add authentication/security for production use

Python/OpenCV Receiver

# Basic rolling display
uv run .\scripts\recv_raw_rolling.py
# With display throttling and recording
uv run .\scripts\recv_raw_rolling.py --display-fps 60 --save-mjpeg .\results\output_60fps.avi
# Max performance (no display, stats only)
uv run .\scripts\recv_raw_rolling.py --no-display

See scripts/recv_raw_rolling.py for the Python implementation with debug options.

UDP Traffic Analysis & Debugging

To inspect and analyze the raw UDP packets being transmitted:

# Detailed payload analyzer - shows format, dimensions, pixel statistics
uv run .\scripts\udp_payload_analyzer.py

Example Output:

================================================================================
PACKET #1 @ 17:45:23.456
================================================================================
Source: 127.0.0.1:52341
Total Size: 7368 bytes

PROTOCOL ANALYSIS:
--------------------------------------------------------------------------------
  protocol            : RAW
  header_size         : 0
  payload_size        : 7368

VIDEO PAYLOAD ANALYSIS:
--------------------------------------------------------------------------------
  📹 Real camera data - Single line 2456x1 BGR
  Format: BGR
  Dimensions: 2456x1
  Channels: 3

PIXEL STATISTICS:
--------------------------------------------------------------------------------
  Channel 0 (B/R)     : min=  0, max=110, mean= 28.63, std= 16.16
  Channel 1 (G)       : min= 17, max=233, mean= 62.39, std= 36.93
  Channel 2 (R/B)     : min= 25, max=255, mean= 99.76, std= 49.81

HEX PREVIEW (first 32 bytes):
--------------------------------------------------------------------------------
  19 2e 4a 12 30 41 0a 2f 3f 01 32 3e 00 32 40 00 31 45 18 2d 4c 1e 2d...

SESSION SUMMARY:
Total Packets: 235
Total Bytes: 1,731,480 (7368 bytes/packet)

The analyzer automatically detects the format, shows pixel statistics per color channel, and provides a hex preview for debugging. Perfect for verifying data transmission and diagnosing issues.

# Simple packet receiver (no analysis, just basic info)
uv run .\scripts\udp_sniffer_raw.py

Real-time Channel Visualization

For live visualization of RGB/BGR channel values across the line sensor, use the real-time plotter.

See scripts/visualize_line_realtime.py for the implementation.

# Basic usage (assumes BGR format, 2456 width, port 5000)
uv run .\scripts\visualize_line_realtime.py
# With custom parameters
uv run .\scripts\visualize_line_realtime.py --format BGR --port 5000 --width 2456 --fps-limit 30

Features:

  • Dual Plot Display:
    • Top plot: Grayscale luminance (weighted: BGR→0.114B+0.587G+0.299R)
    • Bottom plot: Individual RGB/BGR color channels
  • Real-time Statistics:
    • Per-channel min/max/mean/std deviation
    • Display FPS counter
    • Frame counter
  • Optimized Performance:
    • Packet draining (always displays latest frame)
    • Configurable display rate limiting
    • Minimal buffer size to reduce latency

Command-line Options:

Option Default Description
--format BGR Input format (BGR or RGB)
--port 5000 UDP port to receive on
--width 2456 Line width in pixels
--fps-limit 30 Maximum display update rate

Example Output:

The visualization shows live channel data with statistics overlay:

Frame: 1523  FPS: 29.8
Blue : min= 12 max=203 mean= 45.32 std= 28.45
Green: min= 28 max=241 mean= 68.91 std= 35.12
Red  : min= 35 max=255 mean=102.76 std= 48.23
Gray : min= 41.23 max=241.67 mean= 72.45 std= 36.89

Use Cases:

  • Verify camera line sensor is working correctly
  • Monitor real-time brightness and color balance
  • Debug exposure and gain settings
  • Analyze scene illumination changes
  • Quality control and calibration

Close the plot window to exit.


Configuration Notes

INI file is configured with:

  • Start Y = 500 (captures from row 500 of the sensor)
  • Height = 4 pixels
  • Width = 2456 pixels
  • This optimizes for the center region of the sensor

Note: exposure=5 (5ms) may be too fast for some applications. Adjust based on your requirements.


Demo Data (Testing)

Sender (crop to first column, send raw over UDP)

gst-launch-1.0 -v `
    videotestsrc pattern=smpte ! `
    videocrop left=0 right=639 top=0 bottom=0 ! `
    video/x-raw,format=RGB,width=1,height=640,framerate=30/1 ! `
    udpsink host=127.0.0.1 port=5000

GStreamer Receiver (raw UDP → display)

gst-launch-1.0 -v `
    udpsrc port=5000 caps="video/x-raw,format=RGB,width=1,height=640,framerate=30/1" ! `
    videoconvert ! `
    autovideosink