agrobot_base/Python/raspi/pi/state.py

155 lines
5.0 KiB
Python

class ModuleState:
def __init__(self):
self.module_name = "multispectral"
self.version = "0.1.0"
self.payload_format_version = 1
self.status = "idle"
self.status_detail = None
self.last_error = None
self.last_command = None
self.camera_connected = False
self.camera_id = "cam0"
self.initialized = False
self.streaming = False
# Configuração da captura no sensor
self.fps = 10
self.jpeg_quality = 90
self.width = 640
self.height = 480
self.source_bayer_pattern = "GBRG"
self.source_bit_depth = 10
# Configuração do tipo de payload de saída
self.frame_type = "RAW_BRUTO" # RAW_BRUTO | RGB | RGBNIR
self.output_dtype = "uint8" # uint8 | float32
self.output_layout = "CHW" # sempre CHW
self.output_channels = 1
self.output_channel_names = ["RAW10_PACKED"]
self.output_width = 640
self.output_height = 480
self.trigger_enabled = True
self.trigger_pin = 18
self.trigger_active_high = True
self.trigger_pulse_ms = 5.0
self.trigger_settle_delay_ms = 0.0
self.stream_host = None
self.stream_port = None
self.stream_fps = None
self.stream_frame_id = 0
self.codec_family = "none"
self.codec_name = "blosc"
self.codec_params = {
"cname": "zstd",
"clevel": 3,
"shuffle": "BITSHUFFLE",
}
self.ae_enable = True
self.awb_enable = True
self.exposure_time_us = 15000
self.analogue_gain = 1.0
self.colour_gains = [1.0, 1.0]
self.frame_duration_limits = None
self.update_output_spec()
def update_output_spec(self):
if self.frame_type == "RAW_BRUTO":
self.output_layout = "HW"
self.output_channels = 1
self.output_channel_names = ["BAYER"]
self.output_width = self.width
self.output_height = self.height
elif self.frame_type == "RGB":
self.output_layout = "CHW"
self.output_channels = 3
self.output_channel_names = ["R", "G", "B"]
self.output_width = self.width // 2
self.output_height = self.height // 2
elif self.frame_type == "RGBNIR":
self.output_layout = "CHW"
self.output_channels = 5
self.output_channel_names = ["R", "G", "B", "NIR", "RE"]
self.output_width = self.width // 2
self.output_height = self.height // 2
else:
raise ValueError(f"frame_type inválido: {self.frame_type}")
def clear_error(self):
self.last_error = None
if self.status == "error":
self.status = "idle"
self.status_detail = None
def set_error(self, error: str):
self.last_error = str(error)
self.status = "error"
self.status_detail = str(error)
def to_dict(self):
return {
"module": self.module_name,
"version": self.version,
"status": self.status,
"status_detail": self.status_detail,
"last_error": self.last_error,
"last_command": self.last_command,
"camera_connected": self.camera_connected,
"camera_id": self.camera_id,
"initialized": self.initialized,
"streaming": self.streaming,
"fps": self.fps,
"jpeg_quality": self.jpeg_quality,
"width": self.width,
"height": self.height,
"trigger_enabled": self.trigger_enabled,
"trigger_pin": self.trigger_pin,
"trigger_active_high": self.trigger_active_high,
"trigger_pulse_ms": self.trigger_pulse_ms,
"trigger_settle_delay_ms": self.trigger_settle_delay_ms,
"stream_host": self.stream_host,
"stream_port": self.stream_port,
"stream_fps": self.stream_fps,
"stream_frame_id": self.stream_frame_id,
"codec_family": self.codec_family,
"codec_name": self.codec_name,
"codec_params": self.codec_params,
"ae_enable": self.ae_enable,
"awb_enable": self.awb_enable,
"exposure_time_us": self.exposure_time_us,
"analogue_gain": self.analogue_gain,
"colour_gains": self.colour_gains,
"frame_duration_limits": self.frame_duration_limits,
"payload_format_version": self.payload_format_version,
"source_bayer_pattern": self.source_bayer_pattern,
"source_bit_depth": self.source_bit_depth,
"frame_type": self.frame_type,
"output_dtype": self.output_dtype,
"output_layout": self.output_layout,
"output_channels": self.output_channels,
"output_channel_names": self.output_channel_names,
"output_width": self.output_width,
"output_height": self.output_height,
}