feagi-core 2.2.1__tar.gz → 2.2.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {feagi_core-2.2.1 → feagi_core-2.2.3}/PKG-INFO +12 -12
- {feagi_core-2.2.1 → feagi_core-2.2.3}/examples/video_streamer/example_rgbd_pair.py +7 -9
- {feagi_core-2.2.1 → feagi_core-2.2.3}/examples/video_streamer/example_rgbd_realsense.py +18 -20
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/__init__.py +1 -1
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/bin/darwin-aarch64/feagi +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/bin/darwin-x86_64/feagi +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/bin/linux-aarch64/feagi +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/bin/linux-x86_64/feagi +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/bin/windows-x86_64/feagi.exe +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/brain_input.py +16 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/brain_output.py +251 -43
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/connector_utils.py +2 -2
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/inputs/vision.py +6 -14
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/observability/controller_logger.py +2 -3
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/observability/formatters.py +0 -1
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/observability/logger.py +1 -1
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/observability/metrics.py +2 -3
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/observability/monitor.py +1 -2
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/observability/profiler.py +0 -1
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/observability/utils.py +0 -1
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/transports/base.py +1 -1
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/transports/websocket_relay.py +1 -1
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi_core.egg-info/PKG-INFO +12 -12
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi_core.egg-info/SOURCES.txt +1 -1
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi_core.egg-info/requires.txt +11 -11
- {feagi_core-2.2.1 → feagi_core-2.2.3}/pyproject.toml +12 -12
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/bdu/test_neuroembryogenesis.py +6 -7
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_cortical_id_label.py +2 -2
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_rgbd_sdk_helpers.py +26 -14
- feagi_core-2.2.3/tests/test_sensorimotor_area_registration.py +179 -0
- feagi_core-2.2.1/tests/integration/test_snapshot_restore_cortical_areas.py +0 -105
- {feagi_core-2.2.1 → feagi_core-2.2.3}/.pre-commit-config.yaml +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/.ruff.toml +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/LICENSE +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/MANIFEST.in +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/NOTICE +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/README.md +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/examples/esp32_controller/esp32_controller_example.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/examples/example_video_simple.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/examples/genome_vs_connectome/example_genome_vs_connectome.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/examples/mixed_transport_agent/mixed_transport_agent.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/examples/observability/01_basic_metrics.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/examples/observability/02_data_logging.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/examples/observability/03_data_validation.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/examples/observability/04_performance_profiling.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/examples/observability/05_comprehensive_monitoring.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/examples/observability/06_quick_start.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/examples/servo_motor/example_servo_motor.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/examples/simple_robot/example_simple_robot.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/examples/video_streamer/example_video_simple.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/agent/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/agent/base.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/agent/bluetooth.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/agent/esp32.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/agent/video.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/cli/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/cli/bv.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/cli/bv_process.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/cli/feagi_process.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/cli/main.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/cli/process_utils.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/config.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/connectome/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/connectome/api.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/connectome/artifact.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/connectome/model.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/engine/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/engine/manager.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/genome/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/genome/api.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/genome/artifact.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/packaging/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/paths.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/client.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/health_monitor.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/inputs/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/inputs/base.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/inputs/numeric.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/inputs/smart_imu.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/inputs/text.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/observability/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/observability/inspector.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/outputs/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/outputs/base.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/outputs/motor.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/outputs/numeric.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/outputs/text.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/pns/registration_manager.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/transports/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/transports/bluetooth_direct.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi/transports/websocket_client.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi-bv/feagi_bv/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi-bv/feagi_bv/runtime.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi-bv/setup.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi_core.egg-info/dependency_links.txt +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi_core.egg-info/entry_points.txt +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi_core.egg-info/not-zip-safe +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/feagi_core.egg-info/top_level.txt +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/scripts/bump_version.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/scripts/migrate_capabilities_json.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/scripts/test_genome_import.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/setup.cfg +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/setup.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/src/api/routers/v1/inputs.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/src/evo/mapping_helper.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/src/inf/byte_processor.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/src/pns/vision.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/cli/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/cli/test_brain_artifact_options.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/cli/test_bv_process_manager.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/cli/test_config_and_bv.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/cli/test_config_command.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/cli/test_engine_manager_spawn.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/cli/test_feagi_process_manager.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/cli/test_main_interrupt_handling.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/bdu/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/bdu/test_connectome_manager.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/bdu/test_synaptogenesis.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/npu/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/npu/test_optimized_integration.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/npu_bdu_integration.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_cli_config_show.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_cortical_area_expansion.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_cortical_area_parameter_updates.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_cortical_mapping_flow.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_cortical_mapping_reconstruction.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_cross_cortical_synaptic_propagation.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_debug_injection_issue.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_debug_power_area.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_essential_genome_power_injection.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_genome_burst_engine_auto_start.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_genome_connectome_sync.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_intelligent_expansion.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_morphology_dimension_sensitive.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_power_neuron_injection.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_real_world_synaptic_propagation.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_refractory_fire_ledger_api.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_ros_feagi_numeric_roundtrip.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_rust_fcl_workflow.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_rust_pns_visualization.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_sensory_fcl_pipeline.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_video_agent.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/test_video_to_feagi.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/workflows/__init__.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/integration/workflows/test_test_mode_integration.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_brain_input_helpers.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_brain_output_controller_api.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_client.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_connect_duplicate_registration.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_connectome_api.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_connectome_artifact.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_connectome_migration.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_connector_agent_register_callback.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_device_configuration_verification.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_device_registration_contract.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_engine_brain_artifacts.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_genome.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_genome_artifact.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_health_monitor.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_imu_sdk_helpers.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_motor_cortical_id_derivation.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_motor_decode_single_source_guardrail.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_motor_decoder_channel_span.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_motor_registration_tracking.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_recovery_config.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_servo_motor.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_shm_cross_platform.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_smart_imu_input.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_text_token_stream.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tests/test_vision_segmentation.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tools/doc_helpers/convert_html_tables.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tools/doc_helpers/fix_broken_links.py +0 -0
- {feagi_core-2.2.1 → feagi_core-2.2.3}/tools/doc_helpers/fix_html_tables.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: feagi-core
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.3
|
|
4
4
|
Summary: Core SDK for building FEAGI agents, controlling the neural engine, and creating marketplace packages (without Brain Visualizer)
|
|
5
5
|
Author-email: "Neuraville Inc." <feagi@neuraville.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -25,14 +25,14 @@ Requires-Dist: numpy>=1.20.0
|
|
|
25
25
|
Requires-Dist: aiohttp>=3.9.0
|
|
26
26
|
Requires-Dist: toml>=0.10.2
|
|
27
27
|
Requires-Dist: requests>=2.31.0
|
|
28
|
-
Requires-Dist: feagi-rust-py-libs>=0.0.
|
|
28
|
+
Requires-Dist: feagi-rust-py-libs>=0.0.115
|
|
29
29
|
Requires-Dist: pyserial>=3.5
|
|
30
30
|
Provides-Extra: bv
|
|
31
|
-
Requires-Dist: feagi-bv<3.0.0,>=2.
|
|
32
|
-
Requires-Dist: feagi-bv-linux<3.0.0,>=2.
|
|
33
|
-
Requires-Dist: feagi-bv-macos-arm64<3.0.0,>=2.
|
|
34
|
-
Requires-Dist: feagi-bv-macos-x86_64<3.0.0,>=2.
|
|
35
|
-
Requires-Dist: feagi-bv-windows<3.0.0,>=2.
|
|
31
|
+
Requires-Dist: feagi-bv<3.0.0,>=2.6.2; extra == "bv"
|
|
32
|
+
Requires-Dist: feagi-bv-linux<3.0.0,>=2.6.2; sys_platform == "linux" and extra == "bv"
|
|
33
|
+
Requires-Dist: feagi-bv-macos-arm64<3.0.0,>=2.6.2; (sys_platform == "darwin" and platform_machine == "arm64") and extra == "bv"
|
|
34
|
+
Requires-Dist: feagi-bv-macos-x86_64<3.0.0,>=2.6.2; (sys_platform == "darwin" and platform_machine == "x86_64") and extra == "bv"
|
|
35
|
+
Requires-Dist: feagi-bv-windows<3.0.0,>=2.6.2; sys_platform == "win32" and extra == "bv"
|
|
36
36
|
Provides-Extra: video
|
|
37
37
|
Requires-Dist: opencv-python>=4.9.0; extra == "video"
|
|
38
38
|
Provides-Extra: bluetooth
|
|
@@ -60,11 +60,11 @@ Requires-Dist: mkdocs-material>=9.0.0; extra == "docs"
|
|
|
60
60
|
Requires-Dist: mkdocstrings>=0.20.0; extra == "docs"
|
|
61
61
|
Requires-Dist: mkdocstrings-python>=1.0.0; extra == "docs"
|
|
62
62
|
Provides-Extra: full
|
|
63
|
-
Requires-Dist: feagi-bv<3.0.0,>=2.
|
|
64
|
-
Requires-Dist: feagi-bv-linux<3.0.0,>=2.
|
|
65
|
-
Requires-Dist: feagi-bv-macos-arm64<3.0.0,>=2.
|
|
66
|
-
Requires-Dist: feagi-bv-macos-x86_64<3.0.0,>=2.
|
|
67
|
-
Requires-Dist: feagi-bv-windows<3.0.0,>=2.
|
|
63
|
+
Requires-Dist: feagi-bv<3.0.0,>=2.6.2; extra == "full"
|
|
64
|
+
Requires-Dist: feagi-bv-linux<3.0.0,>=2.6.2; sys_platform == "linux" and extra == "full"
|
|
65
|
+
Requires-Dist: feagi-bv-macos-arm64<3.0.0,>=2.6.2; (sys_platform == "darwin" and platform_machine == "arm64") and extra == "full"
|
|
66
|
+
Requires-Dist: feagi-bv-macos-x86_64<3.0.0,>=2.6.2; (sys_platform == "darwin" and platform_machine == "x86_64") and extra == "full"
|
|
67
|
+
Requires-Dist: feagi-bv-windows<3.0.0,>=2.6.2; sys_platform == "win32" and extra == "full"
|
|
68
68
|
Requires-Dist: opencv-python>=4.9.0; extra == "full"
|
|
69
69
|
Requires-Dist: bleak>=0.21.0; extra == "full"
|
|
70
70
|
Requires-Dist: websockets>=12.0; extra == "full"
|
|
@@ -98,16 +98,14 @@ def get_rgb_frame() -> np.ndarray:
|
|
|
98
98
|
return frame
|
|
99
99
|
|
|
100
100
|
|
|
101
|
-
def
|
|
101
|
+
def get_depth_plane() -> np.ndarray:
|
|
102
102
|
"""
|
|
103
103
|
Replace with real depth frame conversion.
|
|
104
104
|
|
|
105
|
-
Expected shape: (H, W
|
|
106
|
-
|
|
105
|
+
Expected shape: (H, W), float32 in [0, 1]. Each pixel's value is the
|
|
106
|
+
normalized depth FEAGI receives as potential; 0 means no return.
|
|
107
107
|
"""
|
|
108
|
-
|
|
109
|
-
depth[:, :, 12] = 1.0
|
|
110
|
-
return depth
|
|
108
|
+
return np.full((240, 320), 0.2, dtype=np.float32)
|
|
111
109
|
|
|
112
110
|
|
|
113
111
|
def main() -> None:
|
|
@@ -140,7 +138,7 @@ def main() -> None:
|
|
|
140
138
|
rgb_group=0,
|
|
141
139
|
depth_group=1,
|
|
142
140
|
rgb_resolution_xy=(320, 240),
|
|
143
|
-
|
|
141
|
+
depth_resolution_xy=(320, 240),
|
|
144
142
|
bundle_id="front_rgbd",
|
|
145
143
|
bundle_type="rgbd_camera",
|
|
146
144
|
frame_change_handling="absolute",
|
|
@@ -150,13 +148,13 @@ def main() -> None:
|
|
|
150
148
|
print("RGBD streaming started. Press Ctrl+C to stop.")
|
|
151
149
|
while True:
|
|
152
150
|
rgb_frame = get_rgb_frame()
|
|
153
|
-
|
|
151
|
+
depth_plane = get_depth_plane()
|
|
154
152
|
brain_output.write_rgbd_tick(
|
|
155
153
|
rgb_group=groups["Vision"],
|
|
156
154
|
depth_group=groups["DepthMap"],
|
|
157
155
|
channel_index=0,
|
|
158
156
|
frame_rgb=rgb_frame,
|
|
159
|
-
|
|
157
|
+
depth_map_xy=depth_plane,
|
|
160
158
|
)
|
|
161
159
|
brain_output.flush_sensory_bytes()
|
|
162
160
|
time.sleep(1.0 / 15.0)
|
|
@@ -109,28 +109,26 @@ def _ensure_auth_token() -> str:
|
|
|
109
109
|
return token
|
|
110
110
|
|
|
111
111
|
|
|
112
|
-
def
|
|
112
|
+
def _depth_frame_to_level_plane(
|
|
113
113
|
depth_mm_frame: np.ndarray,
|
|
114
114
|
*,
|
|
115
115
|
depth_scale: float,
|
|
116
|
-
|
|
116
|
+
depth_levels: int,
|
|
117
117
|
max_depth_m: float,
|
|
118
118
|
) -> np.ndarray:
|
|
119
|
-
"""
|
|
119
|
+
"""
|
|
120
|
+
Project a metric depth frame onto a quantized one-layer plane.
|
|
121
|
+
|
|
122
|
+
Each valid pixel becomes ``level / depth_levels`` with ``level`` in
|
|
123
|
+
``1..=depth_levels``. RealSense reports 0 for no return; those stay 0 so
|
|
124
|
+
they do not fire.
|
|
125
|
+
"""
|
|
120
126
|
depth_meters = depth_mm_frame.astype(np.float32) * float(depth_scale)
|
|
121
127
|
normalized = np.clip(depth_meters / float(max_depth_m), 0.0, 1.0)
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
max_bin,
|
|
127
|
-
)
|
|
128
|
-
height, width = depth_indices.shape
|
|
129
|
-
depth_volume = np.zeros((height, width, depth_bins), dtype=np.float32)
|
|
130
|
-
row_idx = np.arange(height)[:, None]
|
|
131
|
-
col_idx = np.arange(width)[None, :]
|
|
132
|
-
depth_volume[row_idx, col_idx, depth_indices] = 1.0
|
|
133
|
-
return depth_volume
|
|
128
|
+
level = np.rint(normalized * (depth_levels - 1)) + 1.0
|
|
129
|
+
plane = (level / float(depth_levels)).astype(np.float32)
|
|
130
|
+
plane[depth_mm_frame == 0] = 0.0
|
|
131
|
+
return plane
|
|
134
132
|
|
|
135
133
|
|
|
136
134
|
def main() -> None:
|
|
@@ -142,7 +140,7 @@ def main() -> None:
|
|
|
142
140
|
"Install it in your active virtual environment."
|
|
143
141
|
) from import_error
|
|
144
142
|
|
|
145
|
-
|
|
143
|
+
depth_levels = _required_env_int("FEAGI_DEPTH_LEVELS")
|
|
146
144
|
max_depth_m = _required_env_float("FEAGI_RGBD_MAX_DEPTH_M")
|
|
147
145
|
|
|
148
146
|
config_path = _config_path()
|
|
@@ -210,7 +208,7 @@ def main() -> None:
|
|
|
210
208
|
rgb_group=0,
|
|
211
209
|
depth_group=1,
|
|
212
210
|
rgb_resolution_xy=(frame_width, frame_height),
|
|
213
|
-
|
|
211
|
+
depth_resolution_xy=(frame_width, frame_height),
|
|
214
212
|
bundle_id=bundle_id,
|
|
215
213
|
bundle_type="rgbd_camera",
|
|
216
214
|
frame_change_handling="absolute",
|
|
@@ -233,10 +231,10 @@ def main() -> None:
|
|
|
233
231
|
depth_frame.get_data(),
|
|
234
232
|
dtype=np.uint16,
|
|
235
233
|
)
|
|
236
|
-
|
|
234
|
+
depth_plane = _depth_frame_to_level_plane(
|
|
237
235
|
depth_mm_frame,
|
|
238
236
|
depth_scale=depth_scale,
|
|
239
|
-
|
|
237
|
+
depth_levels=depth_levels,
|
|
240
238
|
max_depth_m=max_depth_m,
|
|
241
239
|
)
|
|
242
240
|
|
|
@@ -245,7 +243,7 @@ def main() -> None:
|
|
|
245
243
|
depth_group=groups["DepthMap"],
|
|
246
244
|
channel_index=0,
|
|
247
245
|
frame_rgb=rgb_frame,
|
|
248
|
-
|
|
246
|
+
depth_map_xy=depth_plane,
|
|
249
247
|
)
|
|
250
248
|
brain_output.flush_sensory_bytes()
|
|
251
249
|
except KeyboardInterrupt:
|
|
@@ -18,7 +18,7 @@ Main modules:
|
|
|
18
18
|
- feagi.cli: Command-line tools
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
|
-
__version__ = "2.2.
|
|
21
|
+
__version__ = "2.2.3"
|
|
22
22
|
|
|
23
23
|
# Import key classes for convenience, but keep optional dependencies lazy so
|
|
24
24
|
# `import feagi` does not require platform-specific extras (e.g., pyserial).
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -39,6 +39,7 @@ _SUBTYPE_TO_SENSOR_REGISTER_CANDIDATES = {
|
|
|
39
39
|
b"dpt": ["sensor_depth_map_register", "sensor_DepthMap_register"],
|
|
40
40
|
b"rim": ["sensor_raw_i_m_u_register", "sensor_RawIMU_register"],
|
|
41
41
|
b"sim": ["sensor_smart_i_m_u_register", "sensor_SmartIMU_register"],
|
|
42
|
+
b"aud": ["sensor_audio_input_register", "sensor_AudioInput_register"],
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
|
|
@@ -164,6 +165,21 @@ def register_cortical_areas_with_cache(cache: Any, cortical_area_ids: List[str])
|
|
|
164
165
|
frame_change_handling=frame,
|
|
165
166
|
misc_data_dimensions=dims,
|
|
166
167
|
)
|
|
168
|
+
elif subtype == b"aud":
|
|
169
|
+
audio_properties = cc_data_types.AudioSpectrumProperties.new_linear(
|
|
170
|
+
16000,
|
|
171
|
+
1024,
|
|
172
|
+
512,
|
|
173
|
+
16,
|
|
174
|
+
-80,
|
|
175
|
+
0,
|
|
176
|
+
)
|
|
177
|
+
register_method(
|
|
178
|
+
group=group_id,
|
|
179
|
+
number_channels=1,
|
|
180
|
+
frame_change_handling=frame,
|
|
181
|
+
audio_properties=audio_properties,
|
|
182
|
+
)
|
|
167
183
|
elif subtype in (b"rim", b"sim"):
|
|
168
184
|
# IMU registration mirrors the SignedPercentage_3D / 4D arm
|
|
169
185
|
# signature: (group, number_channels, frame_change_handling,
|
|
@@ -28,6 +28,9 @@ if not logger.handlers:
|
|
|
28
28
|
|
|
29
29
|
# @ruff-skip: module has >100 E501 line-length violations - cleanup task: sdk-lint-cleanup-brain-output
|
|
30
30
|
|
|
31
|
+
# The DepthMap sensory area is one layer; depth rides on each pixel's potential.
|
|
32
|
+
DEPTH_MAP_LAYERS = 1
|
|
33
|
+
|
|
31
34
|
|
|
32
35
|
class BrainOutput:
|
|
33
36
|
"""
|
|
@@ -1221,6 +1224,12 @@ class BrainOutput:
|
|
|
1221
1224
|
image_resolution_xy: tuple[int, int] = (32, 32),
|
|
1222
1225
|
misc_dimensions_xyz: tuple[int, int, int] = (1, 1, 1),
|
|
1223
1226
|
frame_change_handling: Literal["absolute", "incremental"] = "absolute",
|
|
1227
|
+
audio_sample_rate_hz: int = 16000,
|
|
1228
|
+
audio_window_size: int = 1024,
|
|
1229
|
+
audio_hop_size: int = 512,
|
|
1230
|
+
audio_phase_steps: int = 16,
|
|
1231
|
+
audio_magnitude_floor_db: int = -80,
|
|
1232
|
+
audio_magnitude_ceiling_db: int = 0,
|
|
1224
1233
|
) -> Dict[str, int]:
|
|
1225
1234
|
"""
|
|
1226
1235
|
Register sensory units in ConnectorAgent cache using SDK-owned Rust bindings.
|
|
@@ -1231,7 +1240,13 @@ class BrainOutput:
|
|
|
1231
1240
|
Args:
|
|
1232
1241
|
unit_channel_counts: Mapping of FEAGI unit key -> channel count.
|
|
1233
1242
|
Supported keys: ``Vision``, ``RawIMU``, ``SmartIMU``, ``Proximity``,
|
|
1234
|
-
``Servo``, ``Shock``, ``MiscData``, ``DepthMap``, ``CartesianPosition
|
|
1243
|
+
``Servo``, ``Shock``, ``MiscData``, ``DepthMap``, ``CartesianPosition``,
|
|
1244
|
+
``AudioInput``.
|
|
1245
|
+
|
|
1246
|
+
Notes on ``AudioInput``:
|
|
1247
|
+
* Absolute-only. Registers one spectrum area per channel using
|
|
1248
|
+
linear ``AudioSpectrumProperties`` from the ``audio_*`` kwargs
|
|
1249
|
+
(default 16 kHz, 1024-sample window, hop 512, 16 phase steps).
|
|
1235
1250
|
|
|
1236
1251
|
Notes on IMU keys:
|
|
1237
1252
|
* ``RawIMU`` registers ONE cortical unit with three sub-areas
|
|
@@ -1300,6 +1315,18 @@ class BrainOutput:
|
|
|
1300
1315
|
int(misc_dimensions_xyz[1]),
|
|
1301
1316
|
int(misc_dimensions_xyz[2]),
|
|
1302
1317
|
)
|
|
1318
|
+
if "AudioInput" in unit_channel_counts and frame_mode_value != "absolute":
|
|
1319
|
+
raise ValueError("AudioInput only supports frame_change_handling='absolute'.")
|
|
1320
|
+
audio_properties = None
|
|
1321
|
+
if "AudioInput" in unit_channel_counts:
|
|
1322
|
+
audio_properties = frpl.connector_core.data_types.AudioSpectrumProperties.new_linear(
|
|
1323
|
+
int(audio_sample_rate_hz),
|
|
1324
|
+
int(audio_window_size),
|
|
1325
|
+
int(audio_hop_size),
|
|
1326
|
+
int(audio_phase_steps),
|
|
1327
|
+
int(audio_magnitude_floor_db),
|
|
1328
|
+
int(audio_magnitude_ceiling_db),
|
|
1329
|
+
)
|
|
1303
1330
|
|
|
1304
1331
|
sensory_registers = {
|
|
1305
1332
|
"Vision": lambda group, count: self._cache.sensor_Vision_register(
|
|
@@ -1372,6 +1399,12 @@ class BrainOutput:
|
|
|
1372
1399
|
z_neuron_resolution,
|
|
1373
1400
|
positioning,
|
|
1374
1401
|
),
|
|
1402
|
+
"AudioInput": lambda group, count: self._cache.sensor_AudioInput_register(
|
|
1403
|
+
group,
|
|
1404
|
+
count,
|
|
1405
|
+
frame_mode,
|
|
1406
|
+
audio_properties,
|
|
1407
|
+
),
|
|
1375
1408
|
}
|
|
1376
1409
|
|
|
1377
1410
|
unit_groups: Dict[str, int] = {}
|
|
@@ -1398,7 +1431,7 @@ class BrainOutput:
|
|
|
1398
1431
|
rgb_group: int,
|
|
1399
1432
|
depth_group: int,
|
|
1400
1433
|
rgb_resolution_xy: tuple[int, int],
|
|
1401
|
-
|
|
1434
|
+
depth_resolution_xy: tuple[int, int],
|
|
1402
1435
|
bundle_id: str,
|
|
1403
1436
|
bundle_type: str = "rgbd_camera",
|
|
1404
1437
|
frame_change_handling: Literal["absolute", "incremental"] = "absolute",
|
|
@@ -1407,7 +1440,8 @@ class BrainOutput:
|
|
|
1407
1440
|
Register one RGBD camera as sibling Vision + DepthMap sensory units.
|
|
1408
1441
|
|
|
1409
1442
|
This keeps registration deterministic and explicitly paired so FEAGI can
|
|
1410
|
-
treat both streams as one physical camera rig.
|
|
1443
|
+
treat both streams as one physical camera rig. The DepthMap is one layer
|
|
1444
|
+
(``W x H x 1``); depth rides on each pixel's potential.
|
|
1411
1445
|
"""
|
|
1412
1446
|
self._init_cache()
|
|
1413
1447
|
if self._cache is None:
|
|
@@ -1449,9 +1483,9 @@ class BrainOutput:
|
|
|
1449
1483
|
descriptors.ColorChannelLayout.RGB,
|
|
1450
1484
|
)
|
|
1451
1485
|
depth_dims = descriptors.MiscDataDimensions(
|
|
1452
|
-
int(
|
|
1453
|
-
int(
|
|
1454
|
-
|
|
1486
|
+
int(depth_resolution_xy[0]),
|
|
1487
|
+
int(depth_resolution_xy[1]),
|
|
1488
|
+
DEPTH_MAP_LAYERS,
|
|
1455
1489
|
)
|
|
1456
1490
|
self._cache.sensor_Vision_register(
|
|
1457
1491
|
int(rgb_group),
|
|
@@ -1687,6 +1721,172 @@ class BrainOutput:
|
|
|
1687
1721
|
int(window_ms) if window_ms is not None else None,
|
|
1688
1722
|
)
|
|
1689
1723
|
|
|
1724
|
+
def register_motor_audio_output(
|
|
1725
|
+
self,
|
|
1726
|
+
*,
|
|
1727
|
+
group: int,
|
|
1728
|
+
number_channels: int = 1,
|
|
1729
|
+
sample_rate_hz: int = 16000,
|
|
1730
|
+
window_size: int = 1024,
|
|
1731
|
+
hop_size: int = 512,
|
|
1732
|
+
phase_steps: int = 16,
|
|
1733
|
+
magnitude_floor_db: int = -80,
|
|
1734
|
+
magnitude_ceiling_db: int = 0,
|
|
1735
|
+
) -> None:
|
|
1736
|
+
"""Register an AudioOutput motor area (linear spectrum, absolute)."""
|
|
1737
|
+
self._init_cache()
|
|
1738
|
+
if self._cache is None:
|
|
1739
|
+
raise RuntimeError("ConnectorAgent cache is not initialized.")
|
|
1740
|
+
if int(number_channels) <= 0:
|
|
1741
|
+
raise ValueError("AudioOutput number_channels must be > 0.")
|
|
1742
|
+
|
|
1743
|
+
import feagi_rust_py_libs as frpl
|
|
1744
|
+
|
|
1745
|
+
frame_mode = (
|
|
1746
|
+
frpl.data_structures.genomic.cortical_area.FrameChangeHandling.Absolute()
|
|
1747
|
+
)
|
|
1748
|
+
audio_properties = frpl.connector_core.data_types.AudioSpectrumProperties.new_linear(
|
|
1749
|
+
int(sample_rate_hz),
|
|
1750
|
+
int(window_size),
|
|
1751
|
+
int(hop_size),
|
|
1752
|
+
int(phase_steps),
|
|
1753
|
+
int(magnitude_floor_db),
|
|
1754
|
+
int(magnitude_ceiling_db),
|
|
1755
|
+
)
|
|
1756
|
+
self._cache.motor_AudioOutput_register(
|
|
1757
|
+
int(group),
|
|
1758
|
+
int(number_channels),
|
|
1759
|
+
frame_mode,
|
|
1760
|
+
audio_properties,
|
|
1761
|
+
)
|
|
1762
|
+
|
|
1763
|
+
def register_motor_simple_vision_output(
|
|
1764
|
+
self,
|
|
1765
|
+
*,
|
|
1766
|
+
group: int,
|
|
1767
|
+
width: int,
|
|
1768
|
+
height: int,
|
|
1769
|
+
number_channels: int = 1,
|
|
1770
|
+
) -> None:
|
|
1771
|
+
"""Register a SimpleVisionOutput motor area as one RGB image frame."""
|
|
1772
|
+
self._init_cache()
|
|
1773
|
+
if self._cache is None:
|
|
1774
|
+
raise RuntimeError("ConnectorAgent cache is not initialized.")
|
|
1775
|
+
if int(width) <= 0 or int(height) <= 0:
|
|
1776
|
+
raise ValueError("SimpleVisionOutput dimensions must be positive integers.")
|
|
1777
|
+
if int(number_channels) <= 0:
|
|
1778
|
+
raise ValueError("SimpleVisionOutput number_channels must be > 0.")
|
|
1779
|
+
|
|
1780
|
+
import feagi_rust_py_libs as frpl
|
|
1781
|
+
|
|
1782
|
+
frame_mode = (
|
|
1783
|
+
frpl.data_structures.genomic.cortical_area.FrameChangeHandling.Absolute()
|
|
1784
|
+
)
|
|
1785
|
+
descriptors = frpl.connector_core.data_types.descriptors
|
|
1786
|
+
image_properties = descriptors.ImageFrameProperties(
|
|
1787
|
+
descriptors.ImageXYResolution(int(width), int(height)),
|
|
1788
|
+
descriptors.ColorSpace.Gamma,
|
|
1789
|
+
descriptors.ColorChannelLayout.RGB,
|
|
1790
|
+
)
|
|
1791
|
+
self._cache.motor_SimpleVisionOutput_register(
|
|
1792
|
+
int(group),
|
|
1793
|
+
int(number_channels),
|
|
1794
|
+
frame_mode,
|
|
1795
|
+
image_properties,
|
|
1796
|
+
)
|
|
1797
|
+
|
|
1798
|
+
def register_motor_pose_estimation(
|
|
1799
|
+
self,
|
|
1800
|
+
*,
|
|
1801
|
+
group: int,
|
|
1802
|
+
width: int,
|
|
1803
|
+
height: int,
|
|
1804
|
+
depth: int,
|
|
1805
|
+
pose_schema: str = "HumanBody",
|
|
1806
|
+
number_channels: int = 1,
|
|
1807
|
+
) -> None:
|
|
1808
|
+
"""Register a PoseEstimation motor area.
|
|
1809
|
+
|
|
1810
|
+
``pose_schema`` is one of HumanBody, HumanHand, HumanFace, Quadruped,
|
|
1811
|
+
Avian, Arthropod, Object6DoF, or Custom.
|
|
1812
|
+
"""
|
|
1813
|
+
self._init_cache()
|
|
1814
|
+
if self._cache is None:
|
|
1815
|
+
raise RuntimeError("ConnectorAgent cache is not initialized.")
|
|
1816
|
+
if int(width) <= 0 or int(height) <= 0 or int(depth) <= 0:
|
|
1817
|
+
raise ValueError("PoseEstimation dimensions must be positive integers.")
|
|
1818
|
+
if int(number_channels) <= 0:
|
|
1819
|
+
raise ValueError("PoseEstimation number_channels must be > 0.")
|
|
1820
|
+
|
|
1821
|
+
import feagi_rust_py_libs as frpl
|
|
1822
|
+
|
|
1823
|
+
schema_name = str(pose_schema).strip()
|
|
1824
|
+
schema_factory = getattr(
|
|
1825
|
+
frpl.data_structures.genomic.cortical_area.PoseSchema,
|
|
1826
|
+
schema_name,
|
|
1827
|
+
None,
|
|
1828
|
+
)
|
|
1829
|
+
if schema_factory is None:
|
|
1830
|
+
raise ValueError(f"Unknown pose schema '{schema_name}'.")
|
|
1831
|
+
frame_mode = (
|
|
1832
|
+
frpl.data_structures.genomic.cortical_area.FrameChangeHandling.Absolute()
|
|
1833
|
+
)
|
|
1834
|
+
pose_properties = frpl.connector_core.data_types.PoseEstimationProperties(
|
|
1835
|
+
int(width),
|
|
1836
|
+
int(height),
|
|
1837
|
+
int(depth),
|
|
1838
|
+
)
|
|
1839
|
+
self._cache.motor_PoseEstimation_register(
|
|
1840
|
+
int(group),
|
|
1841
|
+
int(number_channels),
|
|
1842
|
+
frame_mode,
|
|
1843
|
+
schema_factory(),
|
|
1844
|
+
pose_properties,
|
|
1845
|
+
)
|
|
1846
|
+
|
|
1847
|
+
def write_sensor_audio_spectrum(
|
|
1848
|
+
self,
|
|
1849
|
+
*,
|
|
1850
|
+
group: int,
|
|
1851
|
+
channel_index: int,
|
|
1852
|
+
frame,
|
|
1853
|
+
) -> None:
|
|
1854
|
+
"""Write one ``AudioSpectrumFrame`` into a registered AudioInput channel."""
|
|
1855
|
+
if self._cache is None:
|
|
1856
|
+
raise RuntimeError("ConnectorAgent cache is not initialized.")
|
|
1857
|
+
self._cache.sensor_audio_input_write(
|
|
1858
|
+
group=int(group),
|
|
1859
|
+
channel_index=int(channel_index),
|
|
1860
|
+
data=frame,
|
|
1861
|
+
)
|
|
1862
|
+
|
|
1863
|
+
def read_motor_audio_spectrum(self, *, group: int, channel_index: int):
|
|
1864
|
+
"""Read the latest decoded AudioOutput spectrum frame."""
|
|
1865
|
+
if self._cache is None:
|
|
1866
|
+
raise RuntimeError("ConnectorAgent cache is not initialized.")
|
|
1867
|
+
return self._cache.motor_audio_output_read_postprocessed_cache_value(
|
|
1868
|
+
int(group),
|
|
1869
|
+
int(channel_index),
|
|
1870
|
+
)
|
|
1871
|
+
|
|
1872
|
+
def read_motor_simple_vision_output(self, *, group: int, channel_index: int):
|
|
1873
|
+
"""Read the latest decoded SimpleVisionOutput image frame."""
|
|
1874
|
+
if self._cache is None:
|
|
1875
|
+
raise RuntimeError("ConnectorAgent cache is not initialized.")
|
|
1876
|
+
return self._cache.motor_simple_vision_output_read_postprocessed_cache_value(
|
|
1877
|
+
int(group),
|
|
1878
|
+
int(channel_index),
|
|
1879
|
+
)
|
|
1880
|
+
|
|
1881
|
+
def read_motor_pose_estimation(self, *, group: int, channel_index: int):
|
|
1882
|
+
"""Read the latest decoded PoseEstimation joint frame."""
|
|
1883
|
+
if self._cache is None:
|
|
1884
|
+
raise RuntimeError("ConnectorAgent cache is not initialized.")
|
|
1885
|
+
return self._cache.motor_pose_estimation_read_postprocessed_cache_value(
|
|
1886
|
+
int(group),
|
|
1887
|
+
int(channel_index),
|
|
1888
|
+
)
|
|
1889
|
+
|
|
1690
1890
|
def _init_sensory_write_helpers(self) -> None:
|
|
1691
1891
|
"""Lazy-init write helper factories for sensory cache writes."""
|
|
1692
1892
|
if (
|
|
@@ -2027,20 +2227,19 @@ class BrainOutput:
|
|
|
2027
2227
|
*,
|
|
2028
2228
|
group: int,
|
|
2029
2229
|
channel_index: int,
|
|
2030
|
-
|
|
2230
|
+
depth_map_xy,
|
|
2031
2231
|
) -> None:
|
|
2032
|
-
"""
|
|
2232
|
+
"""
|
|
2233
|
+
Write one depth plane into the DepthMap sensory cache.
|
|
2234
|
+
|
|
2235
|
+
``depth_map_xy`` is ``(H, W)`` or ``(H, W, 1)`` with values in ``[0, 1]``;
|
|
2236
|
+
each pixel's value is the potential FEAGI receives. Zero means no return.
|
|
2237
|
+
"""
|
|
2033
2238
|
if self._cache is None:
|
|
2034
2239
|
raise RuntimeError("ConnectorAgent cache is not initialized.")
|
|
2035
2240
|
self._init_sensory_write_helpers()
|
|
2036
2241
|
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
depth_array = np.asarray(depth_map_xyz, dtype=np.float32)
|
|
2040
|
-
if depth_array.ndim != 3:
|
|
2041
|
-
raise ValueError(
|
|
2042
|
-
f"Depth map must be a 3D ndarray (H, W, Z), got {depth_array.shape}"
|
|
2043
|
-
)
|
|
2242
|
+
depth_array = BrainOutput._depth_plane(depth_map_xy)
|
|
2044
2243
|
depth_data = self._sensory_misc_factory.new_from_array(depth_array)
|
|
2045
2244
|
self._cache.sensor_depth_map_write(
|
|
2046
2245
|
group=int(group),
|
|
@@ -2049,15 +2248,33 @@ class BrainOutput:
|
|
|
2049
2248
|
)
|
|
2050
2249
|
|
|
2051
2250
|
@staticmethod
|
|
2052
|
-
def
|
|
2251
|
+
def _depth_plane(depth_map_xy):
|
|
2252
|
+
"""Validate a depth plane and return it as ``(H, W, 1)`` float32."""
|
|
2253
|
+
import numpy as np
|
|
2254
|
+
|
|
2255
|
+
depth_array = np.asarray(depth_map_xy, dtype=np.float32)
|
|
2256
|
+
if depth_array.ndim == 2:
|
|
2257
|
+
depth_array = depth_array[:, :, None]
|
|
2258
|
+
if depth_array.ndim != 3 or depth_array.shape[2] != DEPTH_MAP_LAYERS:
|
|
2259
|
+
raise ValueError(
|
|
2260
|
+
"Depth map must be (H, W) or (H, W, 1); depth rides on potential, "
|
|
2261
|
+
f"got {depth_array.shape}"
|
|
2262
|
+
)
|
|
2263
|
+
if np.any(depth_array < 0.0) or np.any(depth_array > 1.0):
|
|
2264
|
+
raise ValueError("Depth map values must be in [0, 1].")
|
|
2265
|
+
return depth_array
|
|
2266
|
+
|
|
2267
|
+
@staticmethod
|
|
2268
|
+
def rgb_frame_to_depth_map_levels(frame_rgb, depth_levels: int):
|
|
2053
2269
|
"""
|
|
2054
|
-
Convert RGB frame to one-
|
|
2270
|
+
Convert an RGB frame to a quantized one-layer depth plane using luminance.
|
|
2055
2271
|
|
|
2056
|
-
|
|
2057
|
-
|
|
2272
|
+
Mirrors the desktop depth path: luminance maps to ``level`` in
|
|
2273
|
+
``1..=depth_levels`` and the pixel potential is ``level / depth_levels``,
|
|
2274
|
+
so every pixel is in ``(0, 1]``. Returns ``(H, W, 1)`` float32.
|
|
2058
2275
|
"""
|
|
2059
|
-
if int(
|
|
2060
|
-
raise ValueError("
|
|
2276
|
+
if int(depth_levels) <= 0:
|
|
2277
|
+
raise ValueError("depth_levels must be > 0.")
|
|
2061
2278
|
import numpy as np
|
|
2062
2279
|
|
|
2063
2280
|
frame_array = np.asarray(frame_rgb, dtype=np.uint8)
|
|
@@ -2071,18 +2288,9 @@ class BrainOutput:
|
|
|
2071
2288
|
+ 0.587 * frame_array[:, :, 1].astype(np.float32)
|
|
2072
2289
|
+ 0.114 * frame_array[:, :, 2].astype(np.float32)
|
|
2073
2290
|
) / 255.0
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
0,
|
|
2078
|
-
max_bin,
|
|
2079
|
-
)
|
|
2080
|
-
height, width = indices.shape
|
|
2081
|
-
depth_map = np.zeros((height, width, int(depth_bins)), dtype=np.float32)
|
|
2082
|
-
row_idx = np.arange(height)[:, None]
|
|
2083
|
-
col_idx = np.arange(width)[None, :]
|
|
2084
|
-
depth_map[row_idx, col_idx, indices] = 1.0
|
|
2085
|
-
return depth_map
|
|
2291
|
+
levels = int(depth_levels)
|
|
2292
|
+
level = np.clip(np.round(luminance * (levels - 1)), 0, levels - 1) + 1.0
|
|
2293
|
+
return (level / float(levels)).astype(np.float32)[:, :, None]
|
|
2086
2294
|
|
|
2087
2295
|
def write_rgbd_tick(
|
|
2088
2296
|
self,
|
|
@@ -2091,14 +2299,14 @@ class BrainOutput:
|
|
|
2091
2299
|
depth_group: int,
|
|
2092
2300
|
channel_index: int,
|
|
2093
2301
|
frame_rgb,
|
|
2094
|
-
|
|
2095
|
-
|
|
2302
|
+
depth_map_xy=None,
|
|
2303
|
+
depth_levels: Optional[int] = None,
|
|
2096
2304
|
) -> None:
|
|
2097
2305
|
"""
|
|
2098
2306
|
Write paired RGB + DepthMap data for one tick.
|
|
2099
2307
|
|
|
2100
|
-
If ``
|
|
2101
|
-
luminance deterministically.
|
|
2308
|
+
If ``depth_map_xy`` is omitted, this derives a quantized depth plane from
|
|
2309
|
+
RGB luminance deterministically.
|
|
2102
2310
|
"""
|
|
2103
2311
|
self.write_sensor_vision_frame(
|
|
2104
2312
|
group=rgb_group,
|
|
@@ -2106,20 +2314,20 @@ class BrainOutput:
|
|
|
2106
2314
|
frame_rgb=frame_rgb,
|
|
2107
2315
|
)
|
|
2108
2316
|
|
|
2109
|
-
resolved_depth_map =
|
|
2317
|
+
resolved_depth_map = depth_map_xy
|
|
2110
2318
|
if resolved_depth_map is None:
|
|
2111
|
-
if
|
|
2319
|
+
if depth_levels is None:
|
|
2112
2320
|
raise ValueError(
|
|
2113
|
-
"
|
|
2321
|
+
"depth_levels must be provided when depth_map_xy is None."
|
|
2114
2322
|
)
|
|
2115
|
-
resolved_depth_map = BrainOutput.
|
|
2323
|
+
resolved_depth_map = BrainOutput.rgb_frame_to_depth_map_levels(
|
|
2116
2324
|
frame_rgb,
|
|
2117
|
-
int(
|
|
2325
|
+
int(depth_levels),
|
|
2118
2326
|
)
|
|
2119
2327
|
self.write_sensor_depth_map(
|
|
2120
2328
|
group=depth_group,
|
|
2121
2329
|
channel_index=channel_index,
|
|
2122
|
-
|
|
2330
|
+
depth_map_xy=resolved_depth_map,
|
|
2123
2331
|
)
|
|
2124
2332
|
|
|
2125
2333
|
def write_sensor_scalar(
|
|
@@ -74,7 +74,7 @@ def load_capabilities_from_file(agent: 'PyConnectorAgent', filepath: Union[str,
|
|
|
74
74
|
f" --input {filepath} \\\n"
|
|
75
75
|
f" --output {filepath.parent / 'capabilities_new.json'}\n"
|
|
76
76
|
)
|
|
77
|
-
except:
|
|
77
|
+
except Exception:
|
|
78
78
|
pass
|
|
79
79
|
|
|
80
80
|
raise
|
|
@@ -139,6 +139,6 @@ def _is_old_format(data: dict) -> bool:
|
|
|
139
139
|
return True
|
|
140
140
|
|
|
141
141
|
return False
|
|
142
|
-
except:
|
|
142
|
+
except Exception:
|
|
143
143
|
return False
|
|
144
144
|
|