isar 1.26.0__tar.gz → 1.26.1__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.0 → isar-1.26.1}/.github/workflows/compile_requirements.yml +1 -1
- {isar-1.26.0 → isar-1.26.1}/.github/workflows/pythonpackage.yml +5 -5
- {isar-1.26.0 → isar-1.26.1}/PKG-INFO +4 -17
- {isar-1.26.0 → isar-1.26.1}/README.md +0 -15
- {isar-1.26.0 → isar-1.26.1}/pyproject.toml +1 -0
- {isar-1.26.0 → isar-1.26.1}/requirements.txt +17 -20
- {isar-1.26.0 → isar-1.26.1}/src/isar/apis/models/start_mission_definition.py +0 -4
- {isar-1.26.0 → isar-1.26.1}/src/isar/apis/schedule/scheduling_controller.py +2 -25
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/settings.py +1 -1
- isar-1.26.1/src/isar/models/communication/queues/events.py +57 -0
- isar-1.26.1/src/isar/models/communication/queues/queue_utils.py +32 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/models/communication/queues/status_queue.py +7 -5
- {isar-1.26.0 → isar-1.26.1}/src/isar/modules.py +26 -13
- {isar-1.26.0 → isar-1.26.1}/src/isar/robot/robot.py +46 -13
- {isar-1.26.0 → isar-1.26.1}/src/isar/robot/robot_start_mission.py +10 -10
- {isar-1.26.0 → isar-1.26.1}/src/isar/robot/robot_status.py +7 -4
- isar-1.26.1/src/isar/robot/robot_stop_mission.py +72 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/robot/robot_task_status.py +6 -6
- {isar-1.26.0 → isar-1.26.1}/src/isar/script.py +7 -7
- {isar-1.26.0 → isar-1.26.1}/src/isar/services/utilities/scheduling_utilities.py +10 -8
- {isar-1.26.0 → isar-1.26.1}/src/isar/state_machine/state_machine.py +19 -72
- {isar-1.26.0 → isar-1.26.1}/src/isar/state_machine/states/blocked_protective_stop.py +4 -12
- isar-1.26.1/src/isar/state_machine/states/idle.py +81 -0
- isar-1.26.1/src/isar/state_machine/states/monitor.py +240 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/state_machine/states/offline.py +5 -1
- {isar-1.26.0 → isar-1.26.1}/src/isar/state_machine/states/paused.py +5 -2
- isar-1.26.1/src/isar/state_machine/states/stop.py +62 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/state_machine/transitions/pause.py +1 -1
- {isar-1.26.0 → isar-1.26.1}/src/isar/state_machine/transitions/resume.py +1 -1
- {isar-1.26.0 → isar-1.26.1}/src/isar/state_machine/transitions/start_mission.py +3 -3
- {isar-1.26.0 → isar-1.26.1}/src/isar/state_machine/transitions/stop.py +9 -2
- {isar-1.26.0 → isar-1.26.1}/src/isar/storage/uploader.py +5 -5
- {isar-1.26.0 → isar-1.26.1}/src/isar.egg-info/PKG-INFO +4 -17
- {isar-1.26.0 → isar-1.26.1}/src/isar.egg-info/SOURCES.txt +2 -5
- {isar-1.26.0 → isar-1.26.1}/tests/conftest.py +9 -5
- {isar-1.26.0 → isar-1.26.1}/tests/integration/turtlebot/test_successful_mission.py +4 -2
- {isar-1.26.0 → isar-1.26.1}/tests/isar/models/communication/test_queues.py +12 -12
- {isar-1.26.0 → isar-1.26.1}/tests/isar/services/utilities/test_scheduling_utilities.py +1 -1
- {isar-1.26.0 → isar-1.26.1}/tests/isar/state_machine/states/test_monitor.py +1 -1
- {isar-1.26.0 → isar-1.26.1}/tests/isar/state_machine/test_state_machine.py +8 -11
- {isar-1.26.0 → isar-1.26.1}/tests/isar/storage/test_uploader.py +2 -2
- isar-1.26.0/.github/workflows/publish_isar_base_image.yml +0 -52
- isar-1.26.0/Dockerfile +0 -41
- isar-1.26.0/docker-compose-turtlebot.yml +0 -30
- isar-1.26.0/docker-compose.yml +0 -22
- isar-1.26.0/src/isar/models/communication/queues/queue_utils.py +0 -27
- isar-1.26.0/src/isar/models/communication/queues/queues.py +0 -37
- isar-1.26.0/src/isar/state_machine/states/idle.py +0 -61
- isar-1.26.0/src/isar/state_machine/states/monitor.py +0 -203
- isar-1.26.0/src/isar/state_machine/states/stop.py +0 -91
- {isar-1.26.0 → isar-1.26.1}/.dockerignore +0 -0
- {isar-1.26.0 → isar-1.26.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {isar-1.26.0 → isar-1.26.1}/.github/ISSUE_TEMPLATE/feature.md +0 -0
- {isar-1.26.0 → isar-1.26.1}/.github/ISSUE_TEMPLATE/improvement.md +0 -0
- {isar-1.26.0 → isar-1.26.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {isar-1.26.0 → isar-1.26.1}/.github/release.yml +0 -0
- {isar-1.26.0 → isar-1.26.1}/.github/workflows/project_automations.yml +0 -0
- {isar-1.26.0 → isar-1.26.1}/.github/workflows/pythonpublish.yml +0 -0
- {isar-1.26.0 → isar-1.26.1}/.github/workflows/stale.yml +0 -0
- {isar-1.26.0 → isar-1.26.1}/.gitignore +0 -0
- {isar-1.26.0 → isar-1.26.1}/.pre-commit-config.yaml +0 -0
- {isar-1.26.0 → isar-1.26.1}/LICENSE +0 -0
- {isar-1.26.0 → isar-1.26.1}/SECURITY.md +0 -0
- {isar-1.26.0 → isar-1.26.1}/docs/Makefile +0 -0
- {isar-1.26.0 → isar-1.26.1}/docs/make.bat +0 -0
- {isar-1.26.0 → isar-1.26.1}/docs/rst_processing.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/docs/source/conf.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/docs/source/index.rst +0 -0
- {isar-1.26.0 → isar-1.26.1}/docs/source/readme_link.md +0 -0
- {isar-1.26.0 → isar-1.26.1}/docs/state_machine_diagram.png +0 -0
- {isar-1.26.0 → isar-1.26.1}/main.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/radixconfig.yml +0 -0
- {isar-1.26.0 → isar-1.26.1}/setup.cfg +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/apis/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/apis/api.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/apis/models/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/apis/models/models.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/apis/robot_control/robot_controller.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/apis/schedule/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/apis/security/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/apis/security/authentication.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/certs/ca-cert.pem +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/configuration_error.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/keyvault/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/keyvault/keyvault_error.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/keyvault/keyvault_service.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/log.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/logging.conf +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/maps/JSP1_intermediate_deck.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/maps/JSP1_weather_deck.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/maps/default_map.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/maps/klab_b.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/maps/klab_compressor.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/maps/klab_turtlebot.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/maps/turtleworld.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/predefined_mission_definition/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/predefined_mission_definition/default_exr.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/predefined_mission_definition/default_mission.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/predefined_mission_definition/default_turtlebot.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/predefined_missions/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/predefined_missions/default.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/predefined_missions/default_turtlebot.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/config/settings.env +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/mission_planner/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/mission_planner/local_planner.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/mission_planner/mission_planner_interface.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/mission_planner/sequential_task_selector.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/mission_planner/task_selector_interface.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/models/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/models/communication/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/models/communication/message.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/models/communication/queues/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/models/communication/queues/queue_io.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/models/communication/queues/queue_timeout_error.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/models/mission_metadata/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/services/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/services/auth/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/services/auth/azure_credentials.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/services/service_connections/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/services/service_connections/mqtt/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/services/service_connections/mqtt/mqtt_client.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/services/service_connections/mqtt/robot_heartbeat_publisher.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/services/service_connections/mqtt/robot_info_publisher.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/services/service_connections/request_handler.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/services/service_connections/stid/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/services/utilities/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/services/utilities/queue_utilities.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/services/utilities/robot_utilities.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/services/utilities/threaded_request.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/state_machine/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/state_machine/states/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/state_machine/states/off.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/state_machine/states_enum.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/state_machine/transitions/fail_mission.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/state_machine/transitions/finish_mission.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/state_machine/transitions/utils.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/storage/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/storage/blob_storage.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/storage/local_storage.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/storage/slimm_storage.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/storage/storage_interface.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar/storage/utilities.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar.egg-info/dependency_links.txt +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar.egg-info/entry_points.txt +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar.egg-info/requires.txt +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/isar.egg-info/top_level.txt +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/models/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/models/exceptions/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/models/exceptions/robot_exceptions.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/models/initialize/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/models/inspection/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/models/inspection/inspection.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/models/mission/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/models/mission/mission.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/models/mission/status.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/models/mission/task.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/models/robots/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/models/robots/battery_state.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/models/robots/media.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/models/robots/robot_model.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/robot_interface.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/telemetry/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/telemetry/mqtt_client.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/telemetry/payloads.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/test_robot_interface.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/utilities/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/utilities/json_service.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/src/robot_interface/utilities/uuid_string_factory.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/integration/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/integration/turtlebot/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/integration/turtlebot/config/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/integration/turtlebot/config/maps/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/integration/turtlebot/config/maps/turtleworld.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/integration/turtlebot/config/missions/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/integration/turtlebot/config/missions/default.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/apis/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/apis/models/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/apis/models/example_mission_definition.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/apis/models/test_start_mission_definition.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/apis/scheduler/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/apis/scheduler/test_scheduler_router.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/apis/security/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/apis/security/test_authentication.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/mission/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/mission/test_mission.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/models/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/models/communication/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/services/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/services/readers/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/services/readers/test_mission_reader.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/services/service_connections/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/services/service_connections/echo/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/services/service_connections/test_base_request_handler.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/services/utilities/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/services/utilities/test_queue_utilities.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/state_machine/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/state_machine/states/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/isar/storage/test_blob_storage.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/mocks/__init__.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/mocks/blob_storage.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/mocks/mission_definition.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/mocks/mqtt_client.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/mocks/pose.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/mocks/request.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/mocks/robot_interface.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/mocks/status.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/mocks/task.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/mocks/token.py +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/test_data/test_map_config/test_map_config.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/test_data/test_mission_not_working.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/test_data/test_mission_working.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/test_data/test_mission_working_no_tasks.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/test_data/test_thermal_image_mission.json +0 -0
- {isar-1.26.0 → isar-1.26.1}/tests/test_modules.py +0 -0
|
@@ -15,7 +15,7 @@ jobs:
|
|
|
15
15
|
strategy:
|
|
16
16
|
fail-fast: false
|
|
17
17
|
matrix:
|
|
18
|
-
python-version: ["3.9", "3.10", "3.11", "3.12"]
|
|
18
|
+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
|
|
19
19
|
|
|
20
20
|
steps:
|
|
21
21
|
- uses: actions/checkout@v4
|
|
@@ -29,13 +29,13 @@ jobs:
|
|
|
29
29
|
run: |
|
|
30
30
|
python -m pip install --upgrade pip
|
|
31
31
|
|
|
32
|
-
- name: Install dependencies with the compiled requirements (for Python 3.
|
|
33
|
-
if: ${{matrix.python-version == '3.
|
|
32
|
+
- name: Install dependencies with the compiled requirements (for Python 3.13)
|
|
33
|
+
if: ${{matrix.python-version == '3.13'}}
|
|
34
34
|
run: |
|
|
35
35
|
pip install -r requirements.txt -e .[dev]
|
|
36
36
|
|
|
37
|
-
- name: Install dependencies based on the pyproject.toml file (for Python 3.9-3.
|
|
38
|
-
if: ${{matrix.python-version != '3.
|
|
37
|
+
- name: Install dependencies based on the pyproject.toml file (for Python 3.9-3.12)
|
|
38
|
+
if: ${{matrix.python-version != '3.13'}}
|
|
39
39
|
run: |
|
|
40
40
|
pip install -e .[dev]
|
|
41
41
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: isar
|
|
3
|
-
Version: 1.26.
|
|
3
|
+
Version: 1.26.1
|
|
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
|
|
@@ -95,6 +95,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
|
95
95
|
Classifier: Programming Language :: Python :: 3.10
|
|
96
96
|
Classifier: Programming Language :: Python :: 3.11
|
|
97
97
|
Classifier: Programming Language :: Python :: 3.12
|
|
98
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
98
99
|
Classifier: Topic :: Scientific/Engineering
|
|
99
100
|
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
100
101
|
Classifier: Topic :: Software Development :: Libraries
|
|
@@ -137,6 +138,7 @@ Requires-Dist: pytest-xdist; extra == "dev"
|
|
|
137
138
|
Requires-Dist: pytest; extra == "dev"
|
|
138
139
|
Requires-Dist: requests-mock; extra == "dev"
|
|
139
140
|
Requires-Dist: ruff; extra == "dev"
|
|
141
|
+
Dynamic: license-file
|
|
140
142
|
|
|
141
143
|
# ISAR
|
|
142
144
|
|
|
@@ -254,21 +256,6 @@ In [this](./src/isar/config/predefined_missions) folder there are predefined def
|
|
|
254
256
|
corresponding to `mission_id=1`. A new mission may be added by adding a new json-file with a mission description. Note,
|
|
255
257
|
the mission IDs must be unique.
|
|
256
258
|
|
|
257
|
-
### Running with docker-compose
|
|
258
|
-
|
|
259
|
-
ISAR may be started with an instance of the [isar-robot](https://github.com/equinor/isar-robot) package by
|
|
260
|
-
|
|
261
|
-
```shell
|
|
262
|
-
docker-compose up --build
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
Provided that the simulator from [isar-turtlebot](https://github.com/equinor/isar-turtlebot) is running ISAR may be
|
|
266
|
-
started with the turtlebot by
|
|
267
|
-
|
|
268
|
-
```shell
|
|
269
|
-
docker-compose -f docker-compose-turtlebot.yml up --build
|
|
270
|
-
```
|
|
271
|
-
|
|
272
259
|
### Configuration
|
|
273
260
|
|
|
274
261
|
The system consists of many configuration variables which may alter the functionality. As an example, it is possible to
|
|
@@ -114,21 +114,6 @@ In [this](./src/isar/config/predefined_missions) folder there are predefined def
|
|
|
114
114
|
corresponding to `mission_id=1`. A new mission may be added by adding a new json-file with a mission description. Note,
|
|
115
115
|
the mission IDs must be unique.
|
|
116
116
|
|
|
117
|
-
### Running with docker-compose
|
|
118
|
-
|
|
119
|
-
ISAR may be started with an instance of the [isar-robot](https://github.com/equinor/isar-robot) package by
|
|
120
|
-
|
|
121
|
-
```shell
|
|
122
|
-
docker-compose up --build
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
Provided that the simulator from [isar-turtlebot](https://github.com/equinor/isar-turtlebot) is running ISAR may be
|
|
126
|
-
started with the turtlebot by
|
|
127
|
-
|
|
128
|
-
```shell
|
|
129
|
-
docker-compose -f docker-compose-turtlebot.yml up --build
|
|
130
|
-
```
|
|
131
|
-
|
|
132
117
|
### Configuration
|
|
133
118
|
|
|
134
119
|
The system consists of many configuration variables which may alter the functionality. As an example, it is possible to
|
|
@@ -19,6 +19,7 @@ classifiers = [
|
|
|
19
19
|
"Programming Language :: Python :: 3.10",
|
|
20
20
|
"Programming Language :: Python :: 3.11",
|
|
21
21
|
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Programming Language :: Python :: 3.13",
|
|
22
23
|
"Topic :: Scientific/Engineering",
|
|
23
24
|
"Topic :: Scientific/Engineering :: Physics",
|
|
24
25
|
"Topic :: Software Development :: Libraries",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#
|
|
2
|
-
# This file is autogenerated by pip-compile with Python 3.
|
|
2
|
+
# This file is autogenerated by pip-compile with Python 3.13
|
|
3
3
|
# by the following command:
|
|
4
4
|
#
|
|
5
5
|
# pip-compile --output-file=requirements.txt pyproject.toml
|
|
@@ -8,7 +8,7 @@ alitra==1.1.3
|
|
|
8
8
|
# via isar (pyproject.toml)
|
|
9
9
|
annotated-types==0.7.0
|
|
10
10
|
# via pydantic
|
|
11
|
-
anyio==4.
|
|
11
|
+
anyio==4.9.0
|
|
12
12
|
# via
|
|
13
13
|
# httpx
|
|
14
14
|
# starlette
|
|
@@ -18,13 +18,13 @@ azure-core==1.32.0
|
|
|
18
18
|
# azure-keyvault-secrets
|
|
19
19
|
# azure-storage-blob
|
|
20
20
|
# opencensus-ext-azure
|
|
21
|
-
azure-identity==1.
|
|
21
|
+
azure-identity==1.21.0
|
|
22
22
|
# via
|
|
23
23
|
# isar (pyproject.toml)
|
|
24
24
|
# opencensus-ext-azure
|
|
25
25
|
azure-keyvault-secrets==4.9.0
|
|
26
26
|
# via isar (pyproject.toml)
|
|
27
|
-
azure-storage-blob==12.
|
|
27
|
+
azure-storage-blob==12.25.0
|
|
28
28
|
# via isar (pyproject.toml)
|
|
29
29
|
backoff==2.2.1
|
|
30
30
|
# via isar (pyproject.toml)
|
|
@@ -43,7 +43,7 @@ click==8.1.8
|
|
|
43
43
|
# via
|
|
44
44
|
# isar (pyproject.toml)
|
|
45
45
|
# uvicorn
|
|
46
|
-
cryptography==44.0.
|
|
46
|
+
cryptography==44.0.2
|
|
47
47
|
# via
|
|
48
48
|
# azure-identity
|
|
49
49
|
# azure-storage-blob
|
|
@@ -54,17 +54,17 @@ dacite==1.9.2
|
|
|
54
54
|
# via
|
|
55
55
|
# alitra
|
|
56
56
|
# isar (pyproject.toml)
|
|
57
|
-
fastapi==0.115.
|
|
57
|
+
fastapi==0.115.12
|
|
58
58
|
# via
|
|
59
59
|
# fastapi-azure-auth
|
|
60
60
|
# isar (pyproject.toml)
|
|
61
|
-
fastapi-azure-auth==5.1.
|
|
61
|
+
fastapi-azure-auth==5.1.1
|
|
62
62
|
# via isar (pyproject.toml)
|
|
63
|
-
google-api-core==2.24.
|
|
63
|
+
google-api-core==2.24.2
|
|
64
64
|
# via opencensus
|
|
65
65
|
google-auth==2.38.0
|
|
66
66
|
# via google-api-core
|
|
67
|
-
googleapis-common-protos==1.
|
|
67
|
+
googleapis-common-protos==1.69.2
|
|
68
68
|
# via google-api-core
|
|
69
69
|
h11==0.14.0
|
|
70
70
|
# via
|
|
@@ -85,13 +85,13 @@ isodate==0.7.2
|
|
|
85
85
|
# via
|
|
86
86
|
# azure-keyvault-secrets
|
|
87
87
|
# azure-storage-blob
|
|
88
|
-
msal==1.
|
|
88
|
+
msal==1.32.0
|
|
89
89
|
# via
|
|
90
90
|
# azure-identity
|
|
91
91
|
# msal-extensions
|
|
92
|
-
msal-extensions==1.
|
|
92
|
+
msal-extensions==1.3.1
|
|
93
93
|
# via azure-identity
|
|
94
|
-
numpy==2.2.
|
|
94
|
+
numpy==2.2.4
|
|
95
95
|
# via
|
|
96
96
|
# alitra
|
|
97
97
|
# isar (pyproject.toml)
|
|
@@ -111,11 +111,9 @@ opencensus-ext-requests==0.8.0
|
|
|
111
111
|
# via isar (pyproject.toml)
|
|
112
112
|
paho-mqtt==2.1.0
|
|
113
113
|
# via isar (pyproject.toml)
|
|
114
|
-
|
|
115
|
-
# via msal-extensions
|
|
116
|
-
proto-plus==1.26.0
|
|
114
|
+
proto-plus==1.26.1
|
|
117
115
|
# via google-api-core
|
|
118
|
-
protobuf==
|
|
116
|
+
protobuf==6.30.1
|
|
119
117
|
# via
|
|
120
118
|
# google-api-core
|
|
121
119
|
# googleapis-common-protos
|
|
@@ -137,14 +135,14 @@ pydantic==2.10.6
|
|
|
137
135
|
# pydantic-settings
|
|
138
136
|
pydantic-core==2.27.2
|
|
139
137
|
# via pydantic
|
|
140
|
-
pydantic-settings==2.8.
|
|
138
|
+
pydantic-settings==2.8.1
|
|
141
139
|
# via isar (pyproject.toml)
|
|
142
140
|
pyjwt[crypto]==2.10.1
|
|
143
141
|
# via
|
|
144
142
|
# fastapi-azure-auth
|
|
145
143
|
# isar (pyproject.toml)
|
|
146
144
|
# msal
|
|
147
|
-
python-dotenv==1.0
|
|
145
|
+
python-dotenv==1.1.0
|
|
148
146
|
# via
|
|
149
147
|
# isar (pyproject.toml)
|
|
150
148
|
# pydantic-settings
|
|
@@ -172,13 +170,12 @@ six==1.17.0
|
|
|
172
170
|
# transitions
|
|
173
171
|
sniffio==1.3.1
|
|
174
172
|
# via anyio
|
|
175
|
-
starlette==0.
|
|
173
|
+
starlette==0.46.1
|
|
176
174
|
# via fastapi
|
|
177
175
|
transitions==0.9.2
|
|
178
176
|
# via isar (pyproject.toml)
|
|
179
177
|
typing-extensions==4.12.2
|
|
180
178
|
# via
|
|
181
|
-
# anyio
|
|
182
179
|
# azure-core
|
|
183
180
|
# azure-identity
|
|
184
181
|
# azure-keyvault-secrets
|
|
@@ -61,7 +61,6 @@ class StartMissionDefinition(BaseModel):
|
|
|
61
61
|
|
|
62
62
|
def to_isar_mission(
|
|
63
63
|
start_mission_definition: StartMissionDefinition,
|
|
64
|
-
return_pose: Optional[InputPose] = None,
|
|
65
64
|
) -> Mission:
|
|
66
65
|
isar_tasks: List[TASKS] = []
|
|
67
66
|
|
|
@@ -69,9 +68,6 @@ def to_isar_mission(
|
|
|
69
68
|
task: TASKS = to_isar_task(task_definition)
|
|
70
69
|
isar_tasks.append(task)
|
|
71
70
|
|
|
72
|
-
if return_pose:
|
|
73
|
-
isar_tasks.append(ReturnToHome(pose=return_pose.to_alitra_pose()))
|
|
74
|
-
|
|
75
71
|
if not isar_tasks:
|
|
76
72
|
raise MissionPlannerError("Mission does not contain any valid tasks")
|
|
77
73
|
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from http import HTTPStatus
|
|
3
|
-
from typing import Optional
|
|
4
3
|
|
|
5
|
-
from alitra import Pose
|
|
6
4
|
from fastapi import Body, HTTPException, Path
|
|
7
5
|
from injector import inject
|
|
8
6
|
|
|
9
7
|
from isar.apis.models.models import (
|
|
10
8
|
ControlMissionResponse,
|
|
11
|
-
InputPose,
|
|
12
9
|
StartMissionResponse,
|
|
13
10
|
TaskResponse,
|
|
14
11
|
)
|
|
@@ -21,12 +18,7 @@ from isar.mission_planner.mission_planner_interface import MissionPlannerError
|
|
|
21
18
|
from isar.services.utilities.scheduling_utilities import SchedulingUtilities
|
|
22
19
|
from isar.state_machine.states_enum import States
|
|
23
20
|
from robot_interface.models.mission.mission import Mission
|
|
24
|
-
from robot_interface.models.mission.task import
|
|
25
|
-
TASKS,
|
|
26
|
-
InspectionTask,
|
|
27
|
-
MoveArm,
|
|
28
|
-
ReturnToHome,
|
|
29
|
-
)
|
|
21
|
+
from robot_interface.models.mission.task import TASKS, InspectionTask, MoveArm
|
|
30
22
|
|
|
31
23
|
|
|
32
24
|
class SchedulingController:
|
|
@@ -45,12 +37,6 @@ class SchedulingController:
|
|
|
45
37
|
title="Mission ID",
|
|
46
38
|
description="ID-number for predefined mission",
|
|
47
39
|
),
|
|
48
|
-
return_pose: Optional[InputPose] = Body(
|
|
49
|
-
default=None,
|
|
50
|
-
description="End pose of the mission. The robot return to the specified "
|
|
51
|
-
"pose after finishing all inspections",
|
|
52
|
-
embed=True,
|
|
53
|
-
),
|
|
54
40
|
) -> StartMissionResponse:
|
|
55
41
|
self.logger.info(f"Received request to start mission with id {mission_id}")
|
|
56
42
|
|
|
@@ -58,9 +44,6 @@ class SchedulingController:
|
|
|
58
44
|
self.scheduling_utilities.verify_state_machine_ready_to_receive_mission(state)
|
|
59
45
|
|
|
60
46
|
mission: Mission = self.scheduling_utilities.get_mission(mission_id)
|
|
61
|
-
if return_pose:
|
|
62
|
-
pose: Pose = return_pose.to_alitra_pose()
|
|
63
|
-
mission.tasks.append(ReturnToHome(pose=pose))
|
|
64
47
|
|
|
65
48
|
self.scheduling_utilities.verify_robot_capable_of_mission(
|
|
66
49
|
mission=mission, robot_capabilities=robot_settings.CAPABILITIES
|
|
@@ -80,12 +63,6 @@ class SchedulingController:
|
|
|
80
63
|
title="Mission Definition",
|
|
81
64
|
description="Description of the mission in json format",
|
|
82
65
|
),
|
|
83
|
-
return_pose: Optional[InputPose] = Body(
|
|
84
|
-
default=None,
|
|
85
|
-
description="End pose of the mission. The robot return to the specified "
|
|
86
|
-
"pose after finishing all inspections",
|
|
87
|
-
embed=True,
|
|
88
|
-
),
|
|
89
66
|
) -> StartMissionResponse:
|
|
90
67
|
self.logger.info("Received request to start new mission")
|
|
91
68
|
|
|
@@ -103,7 +80,7 @@ class SchedulingController:
|
|
|
103
80
|
|
|
104
81
|
try:
|
|
105
82
|
mission: Mission = to_isar_mission(
|
|
106
|
-
start_mission_definition=mission_definition
|
|
83
|
+
start_mission_definition=mission_definition
|
|
107
84
|
)
|
|
108
85
|
except MissionPlannerError as e:
|
|
109
86
|
error_message = f"Bad Request - Cannot create ISAR mission: {e}"
|
|
@@ -51,7 +51,7 @@ class Settings(BaseSettings):
|
|
|
51
51
|
# Determines the number of state transitions that are kept in the log
|
|
52
52
|
STATE_TRANSITIONS_LOG_LENGTH: int = Field(default=20)
|
|
53
53
|
|
|
54
|
-
# Number of attempts to initiate a
|
|
54
|
+
# Number of attempts to initiate a mission before cancelling
|
|
55
55
|
INITIATE_FAILURE_COUNTER_LIMIT: int = Field(default=10)
|
|
56
56
|
|
|
57
57
|
# Number of attempts to request a task status in monitor before cancelling
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from queue import Queue
|
|
2
|
+
|
|
3
|
+
from transitions import State
|
|
4
|
+
|
|
5
|
+
from isar.config.settings import settings
|
|
6
|
+
from isar.models.communication.queues.queue_io import QueueIO
|
|
7
|
+
from isar.models.communication.queues.status_queue import StatusQueue
|
|
8
|
+
from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
|
|
9
|
+
from robot_interface.models.mission.mission import Mission
|
|
10
|
+
from robot_interface.models.mission.status import RobotStatus, TaskStatus
|
|
11
|
+
from robot_interface.models.mission.task import TASKS
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Events:
|
|
15
|
+
def __init__(self) -> None:
|
|
16
|
+
self.api_requests: APIRequests = APIRequests()
|
|
17
|
+
self.state_machine_events: StateMachineEvents = StateMachineEvents()
|
|
18
|
+
self.robot_service_events: RobotServiceEvents = RobotServiceEvents()
|
|
19
|
+
|
|
20
|
+
self.upload_queue: Queue = Queue(maxsize=10)
|
|
21
|
+
|
|
22
|
+
if settings.MQTT_ENABLED:
|
|
23
|
+
self.mqtt_queue: Queue = Queue()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class APIRequests:
|
|
27
|
+
def __init__(self) -> None:
|
|
28
|
+
self.start_mission: QueueIO = QueueIO(input_size=1, output_size=1)
|
|
29
|
+
self.stop_mission: QueueIO = QueueIO(input_size=1, output_size=1)
|
|
30
|
+
self.pause_mission: QueueIO = QueueIO(input_size=1, output_size=1)
|
|
31
|
+
self.resume_mission: QueueIO = QueueIO(input_size=1, output_size=1)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class StateMachineEvents:
|
|
35
|
+
def __init__(self) -> None:
|
|
36
|
+
self.start_mission: Queue[Mission] = Queue(maxsize=1)
|
|
37
|
+
self.stop_mission: Queue[bool] = Queue(maxsize=1)
|
|
38
|
+
self.pause_mission: Queue[bool] = Queue(maxsize=1)
|
|
39
|
+
self.task_status_request: Queue[str] = Queue(maxsize=1)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class RobotServiceEvents:
|
|
43
|
+
def __init__(self) -> None:
|
|
44
|
+
self.task_status_updated: Queue[TaskStatus] = Queue(maxsize=1)
|
|
45
|
+
self.task_status_failed: Queue[ErrorMessage] = Queue(maxsize=1)
|
|
46
|
+
self.mission_started: Queue[bool] = Queue(maxsize=1)
|
|
47
|
+
self.mission_failed: Queue[ErrorMessage] = Queue(maxsize=1)
|
|
48
|
+
self.robot_status_changed: Queue[bool] = Queue(maxsize=1)
|
|
49
|
+
self.mission_failed_to_stop: Queue[ErrorMessage] = Queue(maxsize=1)
|
|
50
|
+
self.mission_successfully_stopped: Queue[bool] = Queue(maxsize=1)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class SharedState:
|
|
54
|
+
def __init__(self) -> None:
|
|
55
|
+
self.state: StatusQueue[State] = StatusQueue()
|
|
56
|
+
self.robot_status: StatusQueue[RobotStatus] = StatusQueue()
|
|
57
|
+
self.state_machine_current_task: StatusQueue[TASKS] = StatusQueue()
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from queue import Empty, Queue
|
|
2
|
+
from typing import Optional, TypeVar
|
|
3
|
+
|
|
4
|
+
from isar.models.communication.queues.status_queue import StatusQueue
|
|
5
|
+
|
|
6
|
+
T = TypeVar("T")
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def trigger_event_without_data(queue: Queue[bool]) -> None:
|
|
10
|
+
queue.put(True)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def trigger_event(queue: Queue[T], data: T) -> None:
|
|
14
|
+
queue.put(data)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def check_shared_state(queue: StatusQueue[T]) -> Optional[T]:
|
|
18
|
+
try:
|
|
19
|
+
return queue.check()
|
|
20
|
+
except Empty:
|
|
21
|
+
return None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def update_shared_state(queue: StatusQueue[T], data: T) -> None:
|
|
25
|
+
queue.update(data)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def check_for_event(queue: Queue[T]) -> Optional[T]:
|
|
29
|
+
try:
|
|
30
|
+
return queue.get(block=False)
|
|
31
|
+
except Empty:
|
|
32
|
+
return None
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
from collections import deque
|
|
2
2
|
from queue import Empty, Queue
|
|
3
|
-
from typing import
|
|
3
|
+
from typing import TypeVar
|
|
4
4
|
|
|
5
|
+
T = TypeVar("T")
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
|
|
8
|
+
class StatusQueue(Queue[T]):
|
|
7
9
|
def __init__(self) -> None:
|
|
8
10
|
super().__init__()
|
|
9
11
|
|
|
10
|
-
def check(self) ->
|
|
12
|
+
def check(self) -> T:
|
|
11
13
|
if not self._qsize():
|
|
12
14
|
raise Empty
|
|
13
15
|
with self.mutex:
|
|
14
16
|
queueList = list(self.queue)
|
|
15
17
|
return queueList.pop()
|
|
16
18
|
|
|
17
|
-
def update(self, item:
|
|
19
|
+
def update(self, item: T):
|
|
18
20
|
with self.mutex:
|
|
19
|
-
self.queue = deque()
|
|
21
|
+
self.queue: deque[T] = deque()
|
|
20
22
|
self.queue.append(item)
|
|
@@ -16,7 +16,7 @@ from isar.mission_planner.local_planner import LocalPlanner
|
|
|
16
16
|
from isar.mission_planner.mission_planner_interface import MissionPlannerInterface
|
|
17
17
|
from isar.mission_planner.sequential_task_selector import SequentialTaskSelector
|
|
18
18
|
from isar.mission_planner.task_selector_interface import TaskSelectorInterface
|
|
19
|
-
from isar.models.communication.queues.
|
|
19
|
+
from isar.models.communication.queues.events import Events, SharedState
|
|
20
20
|
from isar.services.service_connections.request_handler import RequestHandler
|
|
21
21
|
from isar.services.utilities.robot_utilities import RobotUtilities
|
|
22
22
|
from isar.services.utilities.scheduling_utilities import SchedulingUtilities
|
|
@@ -76,11 +76,18 @@ class RobotModule(Module):
|
|
|
76
76
|
return robot_interface.Robot() # type: ignore
|
|
77
77
|
|
|
78
78
|
|
|
79
|
-
class
|
|
79
|
+
class EventsModule(Module):
|
|
80
80
|
@provider
|
|
81
81
|
@singleton
|
|
82
|
-
def
|
|
83
|
-
return
|
|
82
|
+
def provide_events(self) -> Events:
|
|
83
|
+
return Events()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class SharedStateModule(Module):
|
|
87
|
+
@provider
|
|
88
|
+
@singleton
|
|
89
|
+
def provide_shared_state(self) -> SharedState:
|
|
90
|
+
return SharedState()
|
|
84
91
|
|
|
85
92
|
|
|
86
93
|
class RequestHandlerModule(Module):
|
|
@@ -125,13 +132,15 @@ class StateMachineModule(Module):
|
|
|
125
132
|
@singleton
|
|
126
133
|
def provide_state_machine(
|
|
127
134
|
self,
|
|
128
|
-
|
|
135
|
+
events: Events,
|
|
136
|
+
shared_state: SharedState,
|
|
129
137
|
robot: RobotInterface,
|
|
130
138
|
mqtt_client: MqttClientInterface,
|
|
131
139
|
task_selector: TaskSelectorInterface,
|
|
132
140
|
) -> StateMachine:
|
|
133
141
|
return StateMachine(
|
|
134
|
-
|
|
142
|
+
events=events,
|
|
143
|
+
shared_state=shared_state,
|
|
135
144
|
robot=robot,
|
|
136
145
|
mqtt_publisher=mqtt_client,
|
|
137
146
|
task_selector=task_selector,
|
|
@@ -143,12 +152,12 @@ class UploaderModule(Module):
|
|
|
143
152
|
@singleton
|
|
144
153
|
def provide_uploader(
|
|
145
154
|
self,
|
|
146
|
-
|
|
155
|
+
events: Events,
|
|
147
156
|
storage_handlers: List[StorageInterface],
|
|
148
157
|
mqtt_client: MqttClientInterface,
|
|
149
158
|
) -> Uploader:
|
|
150
159
|
return Uploader(
|
|
151
|
-
|
|
160
|
+
events=events,
|
|
152
161
|
storage_handlers=storage_handlers,
|
|
153
162
|
mqtt_publisher=mqtt_client,
|
|
154
163
|
)
|
|
@@ -158,9 +167,12 @@ class SchedulingUtilitiesModule(Module):
|
|
|
158
167
|
@provider
|
|
159
168
|
@singleton
|
|
160
169
|
def provide_scheduling_utilities(
|
|
161
|
-
self,
|
|
170
|
+
self,
|
|
171
|
+
events: Events,
|
|
172
|
+
shared_state: SharedState,
|
|
173
|
+
mission_planner: MissionPlannerInterface,
|
|
162
174
|
) -> SchedulingUtilities:
|
|
163
|
-
return SchedulingUtilities(
|
|
175
|
+
return SchedulingUtilities(events, shared_state, mission_planner)
|
|
164
176
|
|
|
165
177
|
|
|
166
178
|
class RobotUtilitiesModule(Module):
|
|
@@ -180,9 +192,9 @@ class ServiceModule(Module):
|
|
|
180
192
|
class MqttModule(Module):
|
|
181
193
|
@provider
|
|
182
194
|
@singleton
|
|
183
|
-
def provide_mqtt_client(self,
|
|
195
|
+
def provide_mqtt_client(self, events: Events) -> MqttClientInterface:
|
|
184
196
|
if settings.MQTT_ENABLED:
|
|
185
|
-
return MqttPublisher(mqtt_queue=
|
|
197
|
+
return MqttPublisher(mqtt_queue=events.mqtt_queue)
|
|
186
198
|
return None
|
|
187
199
|
|
|
188
200
|
|
|
@@ -196,7 +208,8 @@ class SequentialTaskSelectorModule(Module):
|
|
|
196
208
|
modules: Dict[str, Tuple[Module, Union[str, bool]]] = {
|
|
197
209
|
"api": (APIModule, "required"),
|
|
198
210
|
"authentication": (AuthenticationModule, "required"),
|
|
199
|
-
"
|
|
211
|
+
"events": (EventsModule, "required"),
|
|
212
|
+
"shared_state": (SharedStateModule, "required"),
|
|
200
213
|
"request_handler": (RequestHandlerModule, "required"),
|
|
201
214
|
"robot_package": (RobotModule, settings.ROBOT_PACKAGE),
|
|
202
215
|
"isar_id": (RobotModule, settings.ISAR_ID),
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
from queue import Queue
|
|
2
3
|
from threading import Event
|
|
3
4
|
from typing import Optional
|
|
4
5
|
|
|
5
6
|
from injector import inject
|
|
6
7
|
|
|
7
|
-
from isar.models.communication.queues.
|
|
8
|
+
from isar.models.communication.queues.events import (
|
|
9
|
+
Events,
|
|
10
|
+
RobotServiceEvents,
|
|
11
|
+
SharedState,
|
|
12
|
+
StateMachineEvents,
|
|
13
|
+
)
|
|
8
14
|
from isar.models.communication.queues.queue_utils import check_for_event
|
|
9
|
-
from isar.models.communication.queues.queues import Queues
|
|
10
15
|
from isar.robot.robot_start_mission import RobotStartMissionThread
|
|
11
16
|
from isar.robot.robot_status import RobotStatusThread
|
|
17
|
+
from isar.robot.robot_stop_mission import RobotStopMissionThread
|
|
12
18
|
from isar.robot.robot_task_status import RobotTaskStatusThread
|
|
13
19
|
from robot_interface.robot_interface import RobotInterface
|
|
14
20
|
|
|
@@ -16,13 +22,18 @@ from robot_interface.robot_interface import RobotInterface
|
|
|
16
22
|
class Robot(object):
|
|
17
23
|
|
|
18
24
|
@inject
|
|
19
|
-
def __init__(
|
|
25
|
+
def __init__(
|
|
26
|
+
self, events: Events, robot: RobotInterface, shared_state: SharedState
|
|
27
|
+
):
|
|
20
28
|
self.logger = logging.getLogger("robot")
|
|
21
|
-
self.
|
|
29
|
+
self.state_machine_events: StateMachineEvents = events.state_machine_events
|
|
30
|
+
self.robot_service_events: RobotServiceEvents = events.robot_service_events
|
|
31
|
+
self.shared_state: SharedState = shared_state
|
|
22
32
|
self.robot: RobotInterface = robot
|
|
23
33
|
self.start_mission_thread: Optional[RobotStartMissionThread] = None
|
|
24
34
|
self.robot_status_thread: Optional[RobotStatusThread] = None
|
|
25
35
|
self.robot_task_status_thread: Optional[RobotTaskStatusThread] = None
|
|
36
|
+
self.stop_mission_thread_thread: Optional[RobotStopMissionThread] = None
|
|
26
37
|
self.signal_thread_quitting: Event = Event()
|
|
27
38
|
|
|
28
39
|
def stop(self) -> None:
|
|
@@ -39,12 +50,17 @@ class Robot(object):
|
|
|
39
50
|
and self.robot_status_thread.is_alive()
|
|
40
51
|
):
|
|
41
52
|
self.start_mission_thread.join()
|
|
53
|
+
if (
|
|
54
|
+
self.stop_mission_thread_thread is not None
|
|
55
|
+
and self.stop_mission_thread_thread.is_alive()
|
|
56
|
+
):
|
|
57
|
+
self.stop_mission_thread_thread.join()
|
|
42
58
|
self.robot_status_thread = None
|
|
43
59
|
self.robot_task_status_thread = None
|
|
44
60
|
self.start_mission_thread = None
|
|
45
61
|
|
|
46
|
-
def _check_and_handle_start_mission(self,
|
|
47
|
-
start_mission = check_for_event(
|
|
62
|
+
def _check_and_handle_start_mission(self, event: Queue) -> None:
|
|
63
|
+
start_mission = check_for_event(event)
|
|
48
64
|
if start_mission is not None:
|
|
49
65
|
if (
|
|
50
66
|
self.start_mission_thread is not None
|
|
@@ -55,24 +71,39 @@ class Robot(object):
|
|
|
55
71
|
)
|
|
56
72
|
self.start_mission_thread.join()
|
|
57
73
|
self.start_mission_thread = RobotStartMissionThread(
|
|
58
|
-
self.
|
|
74
|
+
self.robot_service_events,
|
|
59
75
|
self.robot,
|
|
60
76
|
self.signal_thread_quitting,
|
|
61
77
|
start_mission,
|
|
62
78
|
)
|
|
63
79
|
self.start_mission_thread.start()
|
|
64
80
|
|
|
65
|
-
def _check_and_handle_task_status_request(self,
|
|
66
|
-
task_id = check_for_event(
|
|
81
|
+
def _check_and_handle_task_status_request(self, event: Queue[str]) -> None:
|
|
82
|
+
task_id: str = check_for_event(event)
|
|
67
83
|
if task_id:
|
|
68
84
|
self.robot_task_status_thread = RobotTaskStatusThread(
|
|
69
|
-
self.
|
|
85
|
+
self.robot_service_events,
|
|
86
|
+
self.robot,
|
|
87
|
+
self.signal_thread_quitting,
|
|
88
|
+
task_id,
|
|
70
89
|
)
|
|
71
90
|
self.robot_task_status_thread.start()
|
|
72
91
|
|
|
92
|
+
def _check_and_handle_stop_mission(self, event: Queue) -> None:
|
|
93
|
+
if check_for_event(event):
|
|
94
|
+
if (
|
|
95
|
+
self.stop_mission_thread_thread is not None
|
|
96
|
+
and self.start_mission_thread.is_alive()
|
|
97
|
+
):
|
|
98
|
+
return
|
|
99
|
+
self.stop_mission_thread_thread = RobotStopMissionThread(
|
|
100
|
+
self.robot_service_events, self.robot, self.signal_thread_quitting
|
|
101
|
+
)
|
|
102
|
+
self.stop_mission_thread_thread.start()
|
|
103
|
+
|
|
73
104
|
def run(self) -> None:
|
|
74
105
|
self.robot_status_thread = RobotStatusThread(
|
|
75
|
-
self.
|
|
106
|
+
self.robot, self.signal_thread_quitting, self.shared_state
|
|
76
107
|
)
|
|
77
108
|
self.robot_status_thread.start()
|
|
78
109
|
|
|
@@ -81,11 +112,13 @@ class Robot(object):
|
|
|
81
112
|
break
|
|
82
113
|
|
|
83
114
|
self._check_and_handle_start_mission(
|
|
84
|
-
self.
|
|
115
|
+
self.state_machine_events.start_mission
|
|
85
116
|
)
|
|
86
117
|
|
|
87
118
|
self._check_and_handle_task_status_request(
|
|
88
|
-
self.
|
|
119
|
+
self.state_machine_events.task_status_request
|
|
89
120
|
)
|
|
90
121
|
|
|
122
|
+
self._check_and_handle_stop_mission(self.state_machine_events.stop_mission)
|
|
123
|
+
|
|
91
124
|
self.logger.info("Exiting robot service main thread")
|