feathersdk.robot.services.data_monitor_service Module¶
- class feathersdk.robot.services.data_monitor_service.DataMonitorServiceConfig(*, module_name='data_monitor_service', perfmon_enabled=True, perfmon_max_size=50000, perfmon_max_file_size=104857600, perfmon_max_total_size=1073741824, perfmon_op_freq=1.0, candump_enabled=True, candump_max_file_size=104857600, candump_max_total_size=1073741824, candump_op_freq=1.0, telemetry_enabled=True, telemetry_max_file_size=104857600, telemetry_max_total_size=1073741824, telemetry_op_freq=1.0, teensy_message_enabled=True, teensy_message_max_file_size=104857600, teensy_message_max_total_size=1073741824, teensy_message_op_freq=1.0)¶
Bases:
PyDFrozenBaseModelConfiguration for the data monitor service.
- Parameters:
module_name (str)
perfmon_enabled (bool)
perfmon_max_size (int)
perfmon_max_file_size (int)
perfmon_max_total_size (int)
perfmon_op_freq (float)
candump_enabled (bool)
candump_max_file_size (int)
candump_max_total_size (int)
candump_op_freq (float)
telemetry_enabled (bool)
telemetry_max_file_size (int)
telemetry_max_total_size (int)
telemetry_op_freq (float)
teensy_message_enabled (bool)
teensy_message_max_file_size (int)
teensy_message_max_total_size (int)
teensy_message_op_freq (float)
- perfmon_op_freq: float¶
The frequency at which we write new performance monitor data and check for oversized files.
- candump_op_freq: float¶
The frequency at which we will check for oversized files and delete old files, in Hz.
- telemetry_op_freq: float¶
The frequency at which we will check for oversized files and delete old files, in Hz.
- teensy_message_op_freq: float¶
The frequency at which we will check for oversized files and delete old files, in Hz.
- model_config: ClassVar[ConfigDict] = {'frozen': True}¶
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class feathersdk.robot.services.data_monitor_service.DataMonitorService(config, *args, **kwargs)¶
Bases:
RobotModule[DataMonitorServiceConfig]A service that monitors robot data.
- Parameters:
config (DataMonitorServiceConfig)
robot (FeatherRobot)
- class feathersdk.robot.services.data_monitor_service.MonitorBinaryFileWriter(monitor_dir, max_file_size, max_total_size, op_freq)¶
Bases:
AbortableA class that writes binary files for monitoring.
Handles the writing of binary files for monitoring, switching to new files when the current file is full, and deleting old files when the total size of the files exceeds the maximum size.
- Parameters:
monitor_dir (Path) – The directory to write the binary files to, and continually check size of (deleting oldest files if necessary).
max_file_size (int) – The maximum size of each file in bytes. We will write until we have written >= this number of bytes, then switch to the next file. This will not be strictly enforced, as we only check for oversized files at a rate of op_freq Hz.
max_total_size (int) – The maximum total size of all files (for this monitor) in bytes. We will delete the oldest file(s) if the total size of all files in the monitor_dir exceeds this value. This will not be strictly enforced, as we only check for oversized files at a rate of op_freq Hz. We will only delete files that we wrote ourselves in this class. We will never delete the currently active file.
op_freq (float) – The frequency at which we will check for oversized files and delete old files, in Hz.
- class feathersdk.robot.services.data_monitor_service.PerfmonDataWriter¶
Bases:
MonitorBinaryFileWriterEvery _thread_step, checks the performance monitor data and writes it
- Each perfmon data file will look like:
[header_reserved: uint32_le][header_size: uint32_le][header][chunk_1][chunk_2][…][chunk_n]
Where header is a chunk of header_reserved bytes at the start of the file (after the header_reserved and header_size values), the first header_size bytes of which contains a pickled dictionary mapping string event names to their integer indices.
- Each chunk is a chunk of data written each _thread_step of this class containing:
[n_elems: uint32_le][inds: uint16_le * n_elems][times: float32 * n_elems][timestamps: float64 * n_elems]
That is, each chunk starts with the number of elements in the chunk (always > 0), followed by 3 arrays of the same length containing the indices (within the header dictionary) of the event names, the times it took to execute the event, and the timestamps of the event (at the end of the event execution).
NOTE: this class will dynamically update the header when the number of events in the performance monitor changes. It assumes that we can never remove events from the performance monitor.
NOTE: the function execution times are stored as float32. So, we can only exactly store 2**24 - 1 nanoseconds of execution times (~16 milliseconds). However, since python is python, we already don’t actually have nanosecond-level accuracy. In reality, we probably only have on the order of microsecond-level accuracy, in which case we can store ~16 seconds of execution times perfectly. After this, we start to lose precision little by little. I doubt we will ever actually need this level of accuracy, so I’d rather save the space to store more data.
- Parameters:
monitor_dir (Path) – The directory to write the binary files to, and continually check size of (deleting oldest files if necessary).
max_file_size (int) – The maximum size of each file in bytes. We will write until we have written >= this number of bytes, then switch to the next file. This will not be strictly enforced, as we only check for oversized files at a rate of op_freq hz.
max_total_size (int) – The maximum total size of all files (for this monitor) in bytes. We will delete the oldest file(s) if the total size of all files in the monitor_dir exceeds this value. This will not be strictly enforced, as we only check for oversized files at a rate of op_freq hz. We will only delete files that we wrote ourselves in this class. We will never delete the currently active file.
op_freq (float) – The frequency at which we will write new perfmon data and check for oversized files and delete old files.
perf_max_size (int) – The maximum number of performance measurements to store in ring buffer.
- insert_perfmon_data(func_idx, time, timestamp)¶
Insert a performance measurement into the performance monitor.
- feathersdk.robot.services.data_monitor_service.perftime(prefix=None, sample_rate=1.0)¶
Returns a function decorator that performs a function and monitors the monotonic time it takes to execute.
- feathersdk.robot.services.data_monitor_service.perftime_insert(event_name, time, timestamp=None)¶
Insert a performance measurement into the performance monitor.
- class feathersdk.robot.services.data_monitor_service.CandumpDataWriter(monitor_dir, max_file_size, max_total_size, op_freq)¶
Bases:
MonitorBinaryFileWriterWrites candump frames to a binary file as a flat stream of packed
CandumpTelemetryentries.- File layout (no headers between batches):
[entry_0][entry_1]…[entry_n]
- Each entry is 21 bytes (little-endian, packed), matching Teensy
CandumpTelemetry: [info: uint8][can_id: uint32][data: uint8[8]][timestamp_ns: uint64]
Where
infopacks: bus (2 bits), sent (1 bit), extended (1 bit), dlc (4 bits), andtimestamp_nsis the board-synced monotonic time when the frame was sent or received.- write(**kwargs)¶
Write the given data to the current file.
- Parameters:
data – The data to write.
_internal_write – If True, will allow writes during abort() (but not after abort_completed())
args (~P)
kwargs (~P)
- Return type:
R
- class feathersdk.robot.services.data_monitor_service.TelemetryDataWriter(monitor_dir, max_file_size, max_total_size, op_freq)¶
Bases:
MonitorBinaryFileWriterWrites telemetry batches to a binary file.
- File layout (no file-level header; batches concatenated):
[batch_0][batch_1]…[batch_n]
- Each batch is:
[f64le timestamp][u16le num_updates][update_0][update_1]…[update_{num_updates-1}]
- Where
update_imatches TeensyGetTelemetrySingleTelemetryHeader+ values: [u16le telem_idx][u16le n_elems][n_elems * itemsize bytes]
timestampis host monotonic time when the batch was applied (same epoch as logcurrtime()/ candump after Teensy clock sync).payloadis the Teensy body afterGetTelemetryPayloadHeader(thenum_updatescount is stored separately in this batch header, not duplicated insidepayload).- write(**kwargs)¶
Write the given data to the current file.
- Parameters:
data – The data to write.
_internal_write – If True, will allow writes during abort() (but not after abort_completed())
args (~P)
kwargs (~P)
- Return type:
R
- class feathersdk.robot.services.data_monitor_service.TeensyMessageDataWriter(monitor_dir, max_file_size, max_total_size, op_freq)¶
Bases:
MonitorBinaryFileWriterWrites teensy host↔board messages to a binary file.
- File layout (no file-level header; messages concatenated):
[message_0][message_1]…[message_n]
- Each message is:
[f64le timestamp][u8 direction][u32le message_id][u16le opcode][u16le payload_len][payload]
directionis 1 for host→Teensy (sent) and 0 for Teensy→host (received).opcodeis the command opcode on TX and the response opcode on RX.payloadis the message body only (noClientCommandHeader).- write(**kwargs)¶
Write the given data to the current file.
- Parameters:
data – The data to write.
_internal_write – If True, will allow writes during abort() (but not after abort_completed())
args (~P)
kwargs (~P)
- Return type:
R