isar 1.26.2__tar.gz → 1.26.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.
Potentially problematic release.
This version of isar might be problematic. Click here for more details.
- {isar-1.26.2 → isar-1.26.3}/PKG-INFO +2 -2
- {isar-1.26.2 → isar-1.26.3}/pyproject.toml +1 -1
- {isar-1.26.2 → isar-1.26.3}/requirements.txt +21 -16
- {isar-1.26.2 → isar-1.26.3}/src/isar/apis/api.py +4 -4
- {isar-1.26.2 → isar-1.26.3}/src/isar/apis/robot_control/robot_controller.py +1 -1
- {isar-1.26.2 → isar-1.26.3}/src/isar/apis/schedule/scheduling_controller.py +1 -1
- {isar-1.26.2 → isar-1.26.3}/src/isar/apis/security/authentication.py +2 -2
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/log.py +2 -1
- {isar-1.26.2 → isar-1.26.3}/src/isar/mission_planner/local_planner.py +1 -1
- isar-1.26.3/src/isar/modules.py +138 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/robot/robot.py +3 -7
- {isar-1.26.2 → isar-1.26.3}/src/isar/robot/robot_start_mission.py +0 -1
- {isar-1.26.2 → isar-1.26.3}/src/isar/robot/robot_status.py +4 -5
- {isar-1.26.2 → isar-1.26.3}/src/isar/robot/robot_stop_mission.py +0 -1
- {isar-1.26.2 → isar-1.26.3}/src/isar/robot/robot_task_status.py +0 -1
- {isar-1.26.2 → isar-1.26.3}/src/isar/script.py +13 -16
- {isar-1.26.2 → isar-1.26.3}/src/isar/services/utilities/robot_utilities.py +1 -1
- {isar-1.26.2 → isar-1.26.3}/src/isar/services/utilities/scheduling_utilities.py +1 -1
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/state_machine.py +8 -1
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/states/blocked_protective_stop.py +9 -1
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/states/idle.py +7 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/states/monitor.py +12 -1
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/states/offline.py +7 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/states/paused.py +7 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/states/stop.py +6 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/storage/blob_storage.py +1 -1
- {isar-1.26.2 → isar-1.26.3}/src/isar/storage/slimm_storage.py +1 -1
- {isar-1.26.2 → isar-1.26.3}/src/isar/storage/uploader.py +8 -2
- {isar-1.26.2 → isar-1.26.3}/src/isar.egg-info/PKG-INFO +2 -2
- {isar-1.26.2 → isar-1.26.3}/src/isar.egg-info/SOURCES.txt +0 -1
- {isar-1.26.2 → isar-1.26.3}/src/isar.egg-info/requires.txt +1 -1
- isar-1.26.3/tests/conftest.py +194 -0
- {isar-1.26.2 → isar-1.26.3}/tests/integration/turtlebot/test_successful_mission.py +0 -70
- {isar-1.26.2 → isar-1.26.3}/tests/isar/state_machine/test_state_machine.py +81 -99
- {isar-1.26.2 → isar-1.26.3}/tests/isar/storage/test_uploader.py +28 -31
- isar-1.26.2/src/isar/modules.py +0 -247
- isar-1.26.2/tests/conftest.py +0 -150
- isar-1.26.2/tests/test_modules.py +0 -46
- {isar-1.26.2 → isar-1.26.3}/.dockerignore +0 -0
- {isar-1.26.2 → isar-1.26.3}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {isar-1.26.2 → isar-1.26.3}/.github/ISSUE_TEMPLATE/feature.md +0 -0
- {isar-1.26.2 → isar-1.26.3}/.github/ISSUE_TEMPLATE/improvement.md +0 -0
- {isar-1.26.2 → isar-1.26.3}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {isar-1.26.2 → isar-1.26.3}/.github/release.yml +0 -0
- {isar-1.26.2 → isar-1.26.3}/.github/workflows/compile_requirements.yml +0 -0
- {isar-1.26.2 → isar-1.26.3}/.github/workflows/project_automations.yml +0 -0
- {isar-1.26.2 → isar-1.26.3}/.github/workflows/pythonpackage.yml +0 -0
- {isar-1.26.2 → isar-1.26.3}/.github/workflows/pythonpublish.yml +0 -0
- {isar-1.26.2 → isar-1.26.3}/.github/workflows/stale.yml +0 -0
- {isar-1.26.2 → isar-1.26.3}/.gitignore +0 -0
- {isar-1.26.2 → isar-1.26.3}/.pre-commit-config.yaml +0 -0
- {isar-1.26.2 → isar-1.26.3}/LICENSE +0 -0
- {isar-1.26.2 → isar-1.26.3}/README.md +0 -0
- {isar-1.26.2 → isar-1.26.3}/SECURITY.md +0 -0
- {isar-1.26.2 → isar-1.26.3}/docs/Makefile +0 -0
- {isar-1.26.2 → isar-1.26.3}/docs/make.bat +0 -0
- {isar-1.26.2 → isar-1.26.3}/docs/rst_processing.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/docs/source/conf.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/docs/source/index.rst +0 -0
- {isar-1.26.2 → isar-1.26.3}/docs/source/readme_link.md +0 -0
- {isar-1.26.2 → isar-1.26.3}/docs/state_machine_diagram.png +0 -0
- {isar-1.26.2 → isar-1.26.3}/main.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/radixconfig.yml +0 -0
- {isar-1.26.2 → isar-1.26.3}/setup.cfg +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/apis/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/apis/models/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/apis/models/models.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/apis/models/start_mission_definition.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/apis/schedule/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/apis/security/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/certs/ca-cert.pem +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/configuration_error.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/keyvault/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/keyvault/keyvault_error.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/keyvault/keyvault_service.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/logging.conf +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/maps/JSP1_intermediate_deck.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/maps/JSP1_weather_deck.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/maps/default_map.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/maps/klab_b.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/maps/klab_compressor.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/maps/klab_turtlebot.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/maps/turtleworld.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/predefined_mission_definition/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/predefined_mission_definition/default_exr.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/predefined_mission_definition/default_mission.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/predefined_mission_definition/default_turtlebot.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/predefined_missions/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/predefined_missions/default.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/predefined_missions/default_turtlebot.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/settings.env +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/config/settings.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/mission_planner/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/mission_planner/mission_planner_interface.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/mission_planner/sequential_task_selector.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/mission_planner/task_selector_interface.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/models/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/models/communication/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/models/communication/message.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/models/communication/queues/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/models/communication/queues/events.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/models/communication/queues/queue_io.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/models/communication/queues/queue_timeout_error.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/models/communication/queues/queue_utils.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/models/communication/queues/status_queue.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/models/mission_metadata/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/services/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/services/auth/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/services/auth/azure_credentials.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/services/service_connections/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/services/service_connections/mqtt/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/services/service_connections/mqtt/mqtt_client.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/services/service_connections/mqtt/robot_heartbeat_publisher.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/services/service_connections/mqtt/robot_info_publisher.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/services/service_connections/request_handler.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/services/service_connections/stid/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/services/utilities/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/services/utilities/queue_utilities.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/services/utilities/threaded_request.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/states/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/states/off.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/states_enum.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/transitions/fail_mission.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/transitions/finish_mission.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/transitions/pause.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/transitions/resume.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/transitions/start_mission.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/transitions/stop.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/state_machine/transitions/utils.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/storage/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/storage/local_storage.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/storage/storage_interface.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar/storage/utilities.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar.egg-info/dependency_links.txt +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar.egg-info/entry_points.txt +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/isar.egg-info/top_level.txt +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/models/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/models/exceptions/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/models/exceptions/robot_exceptions.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/models/initialize/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/models/inspection/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/models/inspection/inspection.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/models/mission/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/models/mission/mission.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/models/mission/status.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/models/mission/task.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/models/robots/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/models/robots/battery_state.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/models/robots/media.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/models/robots/robot_model.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/robot_interface.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/telemetry/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/telemetry/mqtt_client.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/telemetry/payloads.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/test_robot_interface.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/utilities/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/utilities/json_service.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/src/robot_interface/utilities/uuid_string_factory.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/integration/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/integration/turtlebot/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/integration/turtlebot/config/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/integration/turtlebot/config/maps/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/integration/turtlebot/config/maps/turtleworld.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/integration/turtlebot/config/missions/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/integration/turtlebot/config/missions/default.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/apis/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/apis/models/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/apis/models/example_mission_definition.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/apis/models/test_start_mission_definition.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/apis/scheduler/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/apis/scheduler/test_scheduler_router.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/apis/security/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/apis/security/test_authentication.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/mission/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/mission/test_mission.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/models/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/models/communication/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/models/communication/test_queues.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/services/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/services/readers/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/services/readers/test_mission_reader.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/services/service_connections/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/services/service_connections/echo/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/services/service_connections/test_base_request_handler.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/services/utilities/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/services/utilities/test_queue_utilities.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/services/utilities/test_scheduling_utilities.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/state_machine/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/state_machine/states/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/state_machine/states/test_monitor.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/isar/storage/test_blob_storage.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/mocks/__init__.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/mocks/blob_storage.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/mocks/mission_definition.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/mocks/mqtt_client.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/mocks/pose.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/mocks/request.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/mocks/robot_interface.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/mocks/status.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/mocks/task.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/mocks/token.py +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/test_data/test_map_config/test_map_config.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/test_data/test_mission_not_working.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/test_data/test_mission_working.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/test_data/test_mission_working_no_tasks.json +0 -0
- {isar-1.26.2 → isar-1.26.3}/tests/test_data/test_thermal_image_mission.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: isar
|
|
3
|
-
Version: 1.26.
|
|
3
|
+
Version: 1.26.3
|
|
4
4
|
Summary: Integration and Supervisory control of Autonomous Robots
|
|
5
5
|
Author-email: Equinor ASA <fg_robots_dev@equinor.com>
|
|
6
6
|
License: Eclipse Public License version 2.0
|
|
@@ -111,7 +111,7 @@ Requires-Dist: click
|
|
|
111
111
|
Requires-Dist: dacite
|
|
112
112
|
Requires-Dist: fastapi-azure-auth
|
|
113
113
|
Requires-Dist: fastapi
|
|
114
|
-
Requires-Dist: injector
|
|
114
|
+
Requires-Dist: dependency-injector
|
|
115
115
|
Requires-Dist: numpy
|
|
116
116
|
Requires-Dist: opencensus-ext-azure
|
|
117
117
|
Requires-Dist: opencensus-ext-logging
|
|
@@ -12,7 +12,7 @@ anyio==4.9.0
|
|
|
12
12
|
# via
|
|
13
13
|
# httpx
|
|
14
14
|
# starlette
|
|
15
|
-
azure-core==1.
|
|
15
|
+
azure-core==1.33.0
|
|
16
16
|
# via
|
|
17
17
|
# azure-identity
|
|
18
18
|
# azure-keyvault-secrets
|
|
@@ -24,7 +24,7 @@ azure-identity==1.21.0
|
|
|
24
24
|
# opencensus-ext-azure
|
|
25
25
|
azure-keyvault-secrets==4.9.0
|
|
26
26
|
# via isar (pyproject.toml)
|
|
27
|
-
azure-storage-blob==12.25.
|
|
27
|
+
azure-storage-blob==12.25.1
|
|
28
28
|
# via isar (pyproject.toml)
|
|
29
29
|
backoff==2.2.1
|
|
30
30
|
# via isar (pyproject.toml)
|
|
@@ -62,15 +62,15 @@ fastapi-azure-auth==5.1.1
|
|
|
62
62
|
# via isar (pyproject.toml)
|
|
63
63
|
google-api-core==2.24.2
|
|
64
64
|
# via opencensus
|
|
65
|
-
google-auth==2.
|
|
65
|
+
google-auth==2.39.0
|
|
66
66
|
# via google-api-core
|
|
67
|
-
googleapis-common-protos==1.
|
|
67
|
+
googleapis-common-protos==1.70.0
|
|
68
68
|
# via google-api-core
|
|
69
69
|
h11==0.14.0
|
|
70
70
|
# via
|
|
71
71
|
# httpcore
|
|
72
72
|
# uvicorn
|
|
73
|
-
httpcore==1.0.
|
|
73
|
+
httpcore==1.0.8
|
|
74
74
|
# via httpx
|
|
75
75
|
httpx==0.28.1
|
|
76
76
|
# via fastapi-azure-auth
|
|
@@ -91,7 +91,7 @@ msal==1.32.0
|
|
|
91
91
|
# msal-extensions
|
|
92
92
|
msal-extensions==1.3.1
|
|
93
93
|
# via azure-identity
|
|
94
|
-
numpy==2.2.
|
|
94
|
+
numpy==2.2.5
|
|
95
95
|
# via
|
|
96
96
|
# alitra
|
|
97
97
|
# isar (pyproject.toml)
|
|
@@ -113,7 +113,7 @@ paho-mqtt==2.1.0
|
|
|
113
113
|
# via isar (pyproject.toml)
|
|
114
114
|
proto-plus==1.26.1
|
|
115
115
|
# via google-api-core
|
|
116
|
-
protobuf==6.30.
|
|
116
|
+
protobuf==6.30.2
|
|
117
117
|
# via
|
|
118
118
|
# google-api-core
|
|
119
119
|
# googleapis-common-protos
|
|
@@ -124,18 +124,18 @@ pyasn1==0.6.1
|
|
|
124
124
|
# via
|
|
125
125
|
# pyasn1-modules
|
|
126
126
|
# rsa
|
|
127
|
-
pyasn1-modules==0.4.
|
|
127
|
+
pyasn1-modules==0.4.2
|
|
128
128
|
# via google-auth
|
|
129
129
|
pycparser==2.22
|
|
130
130
|
# via cffi
|
|
131
|
-
pydantic==2.
|
|
131
|
+
pydantic==2.11.3
|
|
132
132
|
# via
|
|
133
133
|
# fastapi
|
|
134
134
|
# isar (pyproject.toml)
|
|
135
135
|
# pydantic-settings
|
|
136
|
-
pydantic-core==2.
|
|
136
|
+
pydantic-core==2.33.1
|
|
137
137
|
# via pydantic
|
|
138
|
-
pydantic-settings==2.
|
|
138
|
+
pydantic-settings==2.9.1
|
|
139
139
|
# via isar (pyproject.toml)
|
|
140
140
|
pyjwt[crypto]==2.10.1
|
|
141
141
|
# via
|
|
@@ -159,7 +159,7 @@ requests==2.32.3
|
|
|
159
159
|
# requests-toolbelt
|
|
160
160
|
requests-toolbelt==1.0.0
|
|
161
161
|
# via isar (pyproject.toml)
|
|
162
|
-
rsa==4.9
|
|
162
|
+
rsa==4.9.1
|
|
163
163
|
# via google-auth
|
|
164
164
|
scipy==1.15.2
|
|
165
165
|
# via alitra
|
|
@@ -170,11 +170,11 @@ six==1.17.0
|
|
|
170
170
|
# transitions
|
|
171
171
|
sniffio==1.3.1
|
|
172
172
|
# via anyio
|
|
173
|
-
starlette==0.46.
|
|
173
|
+
starlette==0.46.2
|
|
174
174
|
# via fastapi
|
|
175
175
|
transitions==0.9.2
|
|
176
176
|
# via isar (pyproject.toml)
|
|
177
|
-
typing-extensions==4.
|
|
177
|
+
typing-extensions==4.13.2
|
|
178
178
|
# via
|
|
179
179
|
# azure-core
|
|
180
180
|
# azure-identity
|
|
@@ -183,9 +183,14 @@ typing-extensions==4.12.2
|
|
|
183
183
|
# fastapi
|
|
184
184
|
# pydantic
|
|
185
185
|
# pydantic-core
|
|
186
|
-
|
|
186
|
+
# typing-inspection
|
|
187
|
+
typing-inspection==0.4.0
|
|
188
|
+
# via
|
|
189
|
+
# pydantic
|
|
190
|
+
# pydantic-settings
|
|
191
|
+
urllib3==2.4.0
|
|
187
192
|
# via requests
|
|
188
|
-
uvicorn==0.34.
|
|
193
|
+
uvicorn==0.34.2
|
|
189
194
|
# via isar (pyproject.toml)
|
|
190
195
|
wrapt==1.17.2
|
|
191
196
|
# via opencensus-ext-requests
|
|
@@ -5,10 +5,10 @@ from typing import List, Union
|
|
|
5
5
|
|
|
6
6
|
import click
|
|
7
7
|
import uvicorn
|
|
8
|
+
from dependency_injector.wiring import inject
|
|
8
9
|
from fastapi import FastAPI, Request, Security
|
|
9
10
|
from fastapi.middleware.cors import CORSMiddleware
|
|
10
11
|
from fastapi.routing import APIRouter
|
|
11
|
-
from injector import inject
|
|
12
12
|
from opencensus.ext.azure.trace_exporter import AzureExporter
|
|
13
13
|
from opencensus.trace.attributes_helper import COMMON_ATTRIBUTES
|
|
14
14
|
from opencensus.trace.samplers import ProbabilitySampler
|
|
@@ -36,14 +36,14 @@ class API:
|
|
|
36
36
|
authenticator: Authenticator,
|
|
37
37
|
scheduling_controller: SchedulingController,
|
|
38
38
|
robot_controller: RobotController,
|
|
39
|
-
|
|
39
|
+
keyvault: Keyvault,
|
|
40
40
|
port: int = settings.API_PORT,
|
|
41
41
|
azure_ai_logging_enabled: bool = settings.LOG_HANDLER_APPLICATION_INSIGHTS_ENABLED,
|
|
42
42
|
) -> None:
|
|
43
43
|
self.authenticator: Authenticator = authenticator
|
|
44
44
|
self.scheduling_controller: SchedulingController = scheduling_controller
|
|
45
45
|
self.robot_controller: RobotController = robot_controller
|
|
46
|
-
self.
|
|
46
|
+
self.keyvault: Keyvault = keyvault
|
|
47
47
|
self.host: str = "0.0.0.0" # Locking uvicorn to use 0.0.0.0
|
|
48
48
|
self.port: int = port
|
|
49
49
|
self.azure_ai_logging_enabled: bool = azure_ai_logging_enabled
|
|
@@ -295,7 +295,7 @@ class API:
|
|
|
295
295
|
def _add_request_logging_middleware(self, app: FastAPI) -> None:
|
|
296
296
|
connection_string: str
|
|
297
297
|
try:
|
|
298
|
-
connection_string = self.
|
|
298
|
+
connection_string = self.keyvault.get_secret(
|
|
299
299
|
"application-insights-connection-string"
|
|
300
300
|
).value
|
|
301
301
|
except KeyvaultError:
|
|
@@ -3,7 +3,7 @@ import logging
|
|
|
3
3
|
from fastapi import Depends
|
|
4
4
|
from fastapi.security.base import SecurityBase
|
|
5
5
|
from fastapi_azure_auth import SingleTenantAzureAuthorizationCodeBearer
|
|
6
|
-
from fastapi_azure_auth.exceptions import
|
|
6
|
+
from fastapi_azure_auth.exceptions import InvalidAuthHttp
|
|
7
7
|
from fastapi_azure_auth.user import User
|
|
8
8
|
from pydantic import BaseModel
|
|
9
9
|
|
|
@@ -35,7 +35,7 @@ async def validate_has_role(user: User = Depends(azure_scheme)) -> None:
|
|
|
35
35
|
Raises a 403 authorization error if not.
|
|
36
36
|
"""
|
|
37
37
|
if settings.REQUIRED_ROLE not in user.roles:
|
|
38
|
-
raise
|
|
38
|
+
raise InvalidAuthHttp(
|
|
39
39
|
"Current user does not possess the required role for this endpoint"
|
|
40
40
|
)
|
|
41
41
|
|
|
@@ -56,7 +56,8 @@ def configure_azure_handler(log_config: dict, keyvault: Keyvault) -> logging.Han
|
|
|
56
56
|
).value
|
|
57
57
|
except KeyvaultError:
|
|
58
58
|
message: str = (
|
|
59
|
-
|
|
59
|
+
"CRITICAL ERROR: Missing connection string for"
|
|
60
|
+
f" Application Insights in key vault '{keyvault.name}'."
|
|
60
61
|
)
|
|
61
62
|
print(f"\n{message} \n")
|
|
62
63
|
raise ConfigurationError(message)
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from importlib import import_module
|
|
3
|
+
|
|
4
|
+
from dependency_injector import containers, providers
|
|
5
|
+
|
|
6
|
+
from isar.apis.api import API
|
|
7
|
+
from isar.apis.robot_control.robot_controller import RobotController
|
|
8
|
+
from isar.apis.schedule.scheduling_controller import SchedulingController
|
|
9
|
+
from isar.apis.security.authentication import Authenticator
|
|
10
|
+
from isar.config.keyvault.keyvault_service import Keyvault
|
|
11
|
+
from isar.config.settings import settings
|
|
12
|
+
from isar.mission_planner.local_planner import LocalPlanner
|
|
13
|
+
from isar.mission_planner.sequential_task_selector import SequentialTaskSelector
|
|
14
|
+
from isar.mission_planner.task_selector_interface import TaskSelectorInterface
|
|
15
|
+
from isar.models.communication.queues.events import Events, SharedState
|
|
16
|
+
from isar.robot.robot import Robot
|
|
17
|
+
from isar.services.service_connections.request_handler import RequestHandler
|
|
18
|
+
from isar.services.utilities.robot_utilities import RobotUtilities
|
|
19
|
+
from isar.services.utilities.scheduling_utilities import SchedulingUtilities
|
|
20
|
+
from isar.state_machine.state_machine import StateMachine
|
|
21
|
+
from isar.storage.blob_storage import BlobStorage
|
|
22
|
+
from isar.storage.local_storage import LocalStorage
|
|
23
|
+
from isar.storage.slimm_storage import SlimmStorage
|
|
24
|
+
from isar.storage.uploader import Uploader
|
|
25
|
+
from robot_interface.telemetry.mqtt_client import MqttPublisher
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ApplicationContainer(containers.DeclarativeContainer):
|
|
29
|
+
config = providers.Configuration(pydantic_settings=[settings])
|
|
30
|
+
|
|
31
|
+
# Core services
|
|
32
|
+
keyvault = providers.Singleton(
|
|
33
|
+
Keyvault,
|
|
34
|
+
keyvault_name=settings.KEYVAULT_NAME,
|
|
35
|
+
client_id=settings.AZURE_CLIENT_ID,
|
|
36
|
+
client_secret=os.environ.get("AZURE_CLIENT_SECRET"),
|
|
37
|
+
tenant_id=settings.AZURE_TENANT_ID,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Events and shared state
|
|
41
|
+
events = providers.Singleton(Events)
|
|
42
|
+
shared_state = providers.Singleton(SharedState)
|
|
43
|
+
|
|
44
|
+
# Robot-related services
|
|
45
|
+
robot_interface = providers.Singleton(
|
|
46
|
+
lambda: import_module(f"{settings.ROBOT_PACKAGE}.robotinterface").Robot()
|
|
47
|
+
)
|
|
48
|
+
robot_utilities = providers.Singleton(RobotUtilities, robot=robot_interface)
|
|
49
|
+
|
|
50
|
+
# API and controllers
|
|
51
|
+
authenticator = providers.Singleton(Authenticator)
|
|
52
|
+
scheduling_utilities = providers.Singleton(
|
|
53
|
+
SchedulingUtilities,
|
|
54
|
+
events=events,
|
|
55
|
+
shared_state=shared_state,
|
|
56
|
+
mission_planner=providers.Singleton(LocalPlanner),
|
|
57
|
+
)
|
|
58
|
+
scheduling_controller = providers.Singleton(
|
|
59
|
+
SchedulingController, scheduling_utilities=scheduling_utilities
|
|
60
|
+
)
|
|
61
|
+
robot_controller = providers.Singleton(
|
|
62
|
+
RobotController, robot_utilities=robot_utilities
|
|
63
|
+
)
|
|
64
|
+
api = providers.Singleton(
|
|
65
|
+
API,
|
|
66
|
+
authenticator=authenticator,
|
|
67
|
+
scheduling_controller=scheduling_controller,
|
|
68
|
+
robot_controller=robot_controller,
|
|
69
|
+
keyvault=keyvault,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# Storage
|
|
73
|
+
local_storage = providers.Singleton(LocalStorage)
|
|
74
|
+
blob_storage = providers.Singleton(BlobStorage, keyvault=keyvault)
|
|
75
|
+
slimm_storage = providers.Singleton(
|
|
76
|
+
SlimmStorage, request_handler=providers.Singleton(RequestHandler)
|
|
77
|
+
)
|
|
78
|
+
storage_handlers = providers.List(local_storage, blob_storage, slimm_storage)
|
|
79
|
+
|
|
80
|
+
# Mqtt client
|
|
81
|
+
mqtt_client = (
|
|
82
|
+
providers.Singleton(
|
|
83
|
+
MqttPublisher,
|
|
84
|
+
mqtt_queue=providers.Callable(events.provided.mqtt_queue),
|
|
85
|
+
)
|
|
86
|
+
if settings.MQTT_ENABLED
|
|
87
|
+
else None
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# State machine
|
|
91
|
+
task_selector = providers.Singleton(
|
|
92
|
+
SequentialTaskSelector
|
|
93
|
+
if settings.TASK_SELECTOR == "sequential"
|
|
94
|
+
else TaskSelectorInterface
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
state_machine = providers.Singleton(
|
|
98
|
+
StateMachine,
|
|
99
|
+
events=events,
|
|
100
|
+
shared_state=shared_state,
|
|
101
|
+
robot=robot_interface,
|
|
102
|
+
mqtt_publisher=mqtt_client,
|
|
103
|
+
task_selector=task_selector,
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Robot
|
|
107
|
+
robot = providers.Singleton(
|
|
108
|
+
Robot, events=events, robot=robot_interface, shared_state=shared_state
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
# Uploader
|
|
112
|
+
uploader = providers.Singleton(
|
|
113
|
+
Uploader,
|
|
114
|
+
events=events,
|
|
115
|
+
storage_handlers=storage_handlers,
|
|
116
|
+
mqtt_publisher=mqtt_client,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def get_injector() -> ApplicationContainer:
|
|
121
|
+
container = ApplicationContainer()
|
|
122
|
+
container.init_resources()
|
|
123
|
+
container.wire(modules=[__name__])
|
|
124
|
+
container.config.from_dict(
|
|
125
|
+
{
|
|
126
|
+
"KEYVAULT_NAME": settings.KEYVAULT_NAME,
|
|
127
|
+
"MQTT_ENABLED": settings.MQTT_ENABLED,
|
|
128
|
+
"TASK_SELECTOR": settings.TASK_SELECTOR,
|
|
129
|
+
}
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
print("Loaded the following module configurations:")
|
|
133
|
+
for provider_name, provider in container.providers.items():
|
|
134
|
+
provider_repr = repr(provider)
|
|
135
|
+
simplified_provider = provider_repr.split(".")[-1].split(">")[0]
|
|
136
|
+
print(f" {provider_name:<20}: {simplified_provider}")
|
|
137
|
+
|
|
138
|
+
return container
|
|
@@ -3,7 +3,7 @@ from queue import Queue
|
|
|
3
3
|
from threading import Event
|
|
4
4
|
from typing import Optional
|
|
5
5
|
|
|
6
|
-
from
|
|
6
|
+
from dependency_injector.wiring import inject
|
|
7
7
|
|
|
8
8
|
from isar.models.communication.queues.events import (
|
|
9
9
|
Events,
|
|
@@ -20,11 +20,10 @@ from robot_interface.robot_interface import RobotInterface
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
class Robot(object):
|
|
23
|
-
|
|
24
23
|
@inject
|
|
25
24
|
def __init__(
|
|
26
25
|
self, events: Events, robot: RobotInterface, shared_state: SharedState
|
|
27
|
-
):
|
|
26
|
+
) -> None:
|
|
28
27
|
self.logger = logging.getLogger("robot")
|
|
29
28
|
self.state_machine_events: StateMachineEvents = events.state_machine_events
|
|
30
29
|
self.robot_service_events: RobotServiceEvents = events.robot_service_events
|
|
@@ -107,10 +106,7 @@ class Robot(object):
|
|
|
107
106
|
)
|
|
108
107
|
self.robot_status_thread.start()
|
|
109
108
|
|
|
110
|
-
while
|
|
111
|
-
if self.signal_thread_quitting.is_set():
|
|
112
|
-
break
|
|
113
|
-
|
|
109
|
+
while not self.signal_thread_quitting.wait(0):
|
|
114
110
|
self._check_and_handle_start_mission(
|
|
115
111
|
self.state_machine_events.start_mission
|
|
116
112
|
)
|
|
@@ -9,7 +9,6 @@ from robot_interface.robot_interface import RobotInterface
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class RobotStatusThread(Thread):
|
|
12
|
-
|
|
13
12
|
def __init__(
|
|
14
13
|
self,
|
|
15
14
|
robot: RobotInterface,
|
|
@@ -21,7 +20,7 @@ class RobotStatusThread(Thread):
|
|
|
21
20
|
self.robot: RobotInterface = robot
|
|
22
21
|
self.signal_thread_quitting: Event = signal_thread_quitting
|
|
23
22
|
self.last_robot_status_poll_time: float = time.time()
|
|
24
|
-
Thread.__init__(self, name="Robot status thread"
|
|
23
|
+
Thread.__init__(self, name="Robot status thread")
|
|
25
24
|
|
|
26
25
|
def stop(self) -> None:
|
|
27
26
|
return
|
|
@@ -35,10 +34,10 @@ class RobotStatusThread(Thread):
|
|
|
35
34
|
)
|
|
36
35
|
|
|
37
36
|
def run(self):
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
break
|
|
37
|
+
if self.signal_thread_quitting.is_set():
|
|
38
|
+
return
|
|
41
39
|
|
|
40
|
+
while not self.signal_thread_quitting.wait(0.001):
|
|
42
41
|
if not self._is_ready_to_poll_for_status():
|
|
43
42
|
continue
|
|
44
43
|
|
|
@@ -5,15 +5,12 @@ from logging import Logger
|
|
|
5
5
|
from threading import Thread
|
|
6
6
|
from typing import Any, List, Tuple
|
|
7
7
|
|
|
8
|
-
from injector import Injector
|
|
9
|
-
|
|
10
8
|
import isar
|
|
11
9
|
from isar.apis.api import API
|
|
12
|
-
from isar.config.keyvault.keyvault_service import Keyvault
|
|
13
10
|
from isar.config.log import setup_loggers
|
|
14
11
|
from isar.config.settings import robot_settings, settings
|
|
15
12
|
from isar.models.communication.queues.events import Events
|
|
16
|
-
from isar.modules import get_injector
|
|
13
|
+
from isar.modules import ApplicationContainer, get_injector
|
|
17
14
|
from isar.robot.robot import Robot
|
|
18
15
|
from isar.services.service_connections.mqtt.mqtt_client import MqttClient
|
|
19
16
|
from isar.services.service_connections.mqtt.robot_heartbeat_publisher import (
|
|
@@ -83,19 +80,19 @@ def print_startup_info():
|
|
|
83
80
|
|
|
84
81
|
|
|
85
82
|
def start() -> None:
|
|
86
|
-
injector:
|
|
83
|
+
injector: ApplicationContainer = get_injector()
|
|
87
84
|
|
|
88
|
-
|
|
89
|
-
setup_loggers(keyvault=
|
|
85
|
+
keyvault = injector.keyvault()
|
|
86
|
+
setup_loggers(keyvault=keyvault)
|
|
90
87
|
logger: Logger = logging.getLogger("main")
|
|
91
88
|
|
|
92
89
|
print_startup_info()
|
|
93
90
|
|
|
94
|
-
state_machine: StateMachine = injector.
|
|
95
|
-
uploader: Uploader = injector.
|
|
96
|
-
|
|
97
|
-
events: Events = injector.
|
|
98
|
-
|
|
91
|
+
state_machine: StateMachine = injector.state_machine()
|
|
92
|
+
uploader: Uploader = injector.uploader()
|
|
93
|
+
robot_interface: RobotInterface = injector.robot_interface()
|
|
94
|
+
events: Events = injector.events()
|
|
95
|
+
robot: Robot = injector.robot()
|
|
99
96
|
|
|
100
97
|
threads: List[Thread] = []
|
|
101
98
|
|
|
@@ -110,7 +107,7 @@ def start() -> None:
|
|
|
110
107
|
threads.append(uploader_thread)
|
|
111
108
|
|
|
112
109
|
robot_service_thread: Thread = Thread(
|
|
113
|
-
target=
|
|
110
|
+
target=robot.run, name="Robot service", daemon=True
|
|
114
111
|
)
|
|
115
112
|
threads.append(robot_service_thread)
|
|
116
113
|
|
|
@@ -123,7 +120,7 @@ def start() -> None:
|
|
|
123
120
|
)
|
|
124
121
|
state_machine.events.upload_queue.put(message)
|
|
125
122
|
|
|
126
|
-
|
|
123
|
+
robot_interface.register_inspection_callback(inspections_callback)
|
|
127
124
|
|
|
128
125
|
if settings.MQTT_ENABLED:
|
|
129
126
|
mqtt_client: MqttClient = MqttClient(mqtt_queue=events.mqtt_queue)
|
|
@@ -154,7 +151,7 @@ def start() -> None:
|
|
|
154
151
|
)
|
|
155
152
|
threads.append(robot_heartbeat_thread)
|
|
156
153
|
|
|
157
|
-
publishers: List[Thread] =
|
|
154
|
+
publishers: List[Thread] = robot_interface.get_telemetry_publishers(
|
|
158
155
|
queue=events.mqtt_queue,
|
|
159
156
|
robot_name=settings.ROBOT_NAME,
|
|
160
157
|
isar_id=settings.ISAR_ID,
|
|
@@ -163,7 +160,7 @@ def start() -> None:
|
|
|
163
160
|
if publishers:
|
|
164
161
|
threads.extend(publishers)
|
|
165
162
|
|
|
166
|
-
api: API = injector.
|
|
163
|
+
api: API = injector.api()
|
|
167
164
|
api_thread: Thread = Thread(target=api.run_app, name="ISAR API", daemon=True)
|
|
168
165
|
threads.append(api_thread)
|
|
169
166
|
|
|
@@ -4,8 +4,8 @@ from http import HTTPStatus
|
|
|
4
4
|
from queue import Empty
|
|
5
5
|
from typing import Any, List
|
|
6
6
|
|
|
7
|
+
from dependency_injector.wiring import inject
|
|
7
8
|
from fastapi import HTTPException
|
|
8
|
-
from injector import inject
|
|
9
9
|
from requests import HTTPError
|
|
10
10
|
|
|
11
11
|
from isar.apis.models.models import ControlMissionResponse
|
|
@@ -2,9 +2,10 @@ import json
|
|
|
2
2
|
import logging
|
|
3
3
|
from collections import deque
|
|
4
4
|
from datetime import datetime, timezone
|
|
5
|
+
from threading import Event
|
|
5
6
|
from typing import Deque, List, Optional
|
|
6
7
|
|
|
7
|
-
from
|
|
8
|
+
from dependency_injector.wiring import inject
|
|
8
9
|
from transitions import Machine
|
|
9
10
|
from transitions.core import State
|
|
10
11
|
|
|
@@ -97,6 +98,8 @@ class StateMachine(object):
|
|
|
97
98
|
self.mqtt_publisher: Optional[MqttClientInterface] = mqtt_publisher
|
|
98
99
|
self.task_selector: TaskSelectorInterface = task_selector
|
|
99
100
|
|
|
101
|
+
self.signal_state_machine_to_stop: Event = Event()
|
|
102
|
+
|
|
100
103
|
# List of states
|
|
101
104
|
self.stop_state: State = Stop(self)
|
|
102
105
|
self.paused_state: State = Paused(self)
|
|
@@ -237,6 +240,10 @@ class StateMachine(object):
|
|
|
237
240
|
"""Starts the state machine. Transitions into idle state."""
|
|
238
241
|
self.to_idle() # type: ignore
|
|
239
242
|
|
|
243
|
+
def terminate(self):
|
|
244
|
+
self.logger.info("Stopping state machine")
|
|
245
|
+
self.signal_state_machine_to_stop.set()
|
|
246
|
+
|
|
240
247
|
def iterate_current_task(self):
|
|
241
248
|
if self.current_task.is_finished():
|
|
242
249
|
try:
|
|
@@ -21,6 +21,7 @@ class BlockedProtectiveStop(State):
|
|
|
21
21
|
self.logger = logging.getLogger("state_machine")
|
|
22
22
|
self.robot_status_thread: Optional[ThreadedRequest] = None
|
|
23
23
|
self.shared_state = self.state_machine.shared_state
|
|
24
|
+
self.signal_state_machine_to_stop = state_machine.signal_state_machine_to_stop
|
|
24
25
|
|
|
25
26
|
def start(self) -> None:
|
|
26
27
|
self.state_machine.update_state()
|
|
@@ -31,8 +32,15 @@ class BlockedProtectiveStop(State):
|
|
|
31
32
|
|
|
32
33
|
def _run(self) -> None:
|
|
33
34
|
while True:
|
|
34
|
-
|
|
35
|
+
if self.signal_state_machine_to_stop.is_set():
|
|
36
|
+
self.logger.info(
|
|
37
|
+
"Stopping state machine from %s state", self.__class__.__name__
|
|
38
|
+
)
|
|
39
|
+
break
|
|
35
40
|
|
|
41
|
+
robot_status: RobotStatus = check_shared_state(
|
|
42
|
+
self.shared_state.robot_status
|
|
43
|
+
)
|
|
36
44
|
if robot_status == RobotStatus.Offline:
|
|
37
45
|
transition = self.state_machine.robot_turned_offline # type: ignore
|
|
38
46
|
break
|
|
@@ -25,6 +25,7 @@ class Idle(State):
|
|
|
25
25
|
self.last_robot_status_poll_time: float = time.time()
|
|
26
26
|
self.events = self.state_machine.events
|
|
27
27
|
self.shared_state = self.state_machine.shared_state
|
|
28
|
+
self.signal_state_machine_to_stop = state_machine.signal_state_machine_to_stop
|
|
28
29
|
|
|
29
30
|
def start(self) -> None:
|
|
30
31
|
self.state_machine.update_state()
|
|
@@ -63,6 +64,12 @@ class Idle(State):
|
|
|
63
64
|
|
|
64
65
|
def _run(self) -> None:
|
|
65
66
|
while True:
|
|
67
|
+
if self.signal_state_machine_to_stop.is_set():
|
|
68
|
+
self.logger.info(
|
|
69
|
+
"Stopping state machine from %s state", self.__class__.__name__
|
|
70
|
+
)
|
|
71
|
+
break
|
|
72
|
+
|
|
66
73
|
if self._check_and_handle_stop_mission_event(
|
|
67
74
|
self.events.api_requests.stop_mission.input
|
|
68
75
|
):
|