isar 1.33.4__tar.gz → 1.33.6__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.
- {isar-1.33.4 → isar-1.33.6}/PKG-INFO +1 -1
- {isar-1.33.4 → isar-1.33.6}/requirements.txt +38 -38
- {isar-1.33.4 → isar-1.33.6}/src/isar/apis/api.py +34 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/apis/models/models.py +5 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/apis/robot_control/robot_controller.py +5 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/apis/schedule/scheduling_controller.py +45 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/settings.py +1 -1
- {isar-1.33.4 → isar-1.33.6}/src/isar/models/events.py +17 -1
- {isar-1.33.4 → isar-1.33.6}/src/isar/robot/robot.py +32 -0
- isar-1.33.6/src/isar/robot/robot_pause_mission.py +63 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/robot/robot_stop_mission.py +1 -1
- {isar-1.33.4 → isar-1.33.6}/src/isar/services/utilities/scheduling_utilities.py +50 -4
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/state_machine.py +27 -7
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/states/await_next_mission.py +19 -1
- isar-1.33.6/src/isar/state_machine/states/going_to_lockdown.py +80 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/states/home.py +15 -0
- isar-1.33.6/src/isar/state_machine/states/lockdown.py +37 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/states/monitor.py +16 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/states/paused.py +19 -1
- isar-1.33.6/src/isar/state_machine/states/pausing.py +74 -0
- isar-1.33.6/src/isar/state_machine/states/pausing_return_home.py +74 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/states/recharging.py +16 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/states/return_home_paused.py +17 -1
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/states/returning_home.py +18 -2
- isar-1.33.6/src/isar/state_machine/states/stopping_go_to_lockdown.py +79 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/states_enum.py +5 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/transitions/functions/fail_mission.py +7 -0
- isar-1.33.6/src/isar/state_machine/transitions/functions/pause.py +31 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/transitions/mission.py +55 -10
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/transitions/return_home.py +53 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar.egg-info/PKG-INFO +1 -1
- {isar-1.33.4 → isar-1.33.6}/src/isar.egg-info/SOURCES.txt +6 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/models/exceptions/robot_exceptions.py +11 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/models/mission/status.py +2 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/state_machine/test_state_machine.py +456 -0
- isar-1.33.4/src/isar/state_machine/transitions/functions/pause.py +0 -91
- {isar-1.33.4 → isar-1.33.6}/.dockerignore +0 -0
- {isar-1.33.4 → isar-1.33.6}/.env.test +0 -0
- {isar-1.33.4 → isar-1.33.6}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {isar-1.33.4 → isar-1.33.6}/.github/ISSUE_TEMPLATE/feature.md +0 -0
- {isar-1.33.4 → isar-1.33.6}/.github/ISSUE_TEMPLATE/improvement.md +0 -0
- {isar-1.33.4 → isar-1.33.6}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {isar-1.33.4 → isar-1.33.6}/.github/release.yml +0 -0
- {isar-1.33.4 → isar-1.33.6}/.github/workflows/compile_requirements.yml +0 -0
- {isar-1.33.4 → isar-1.33.6}/.github/workflows/project_automations.yml +0 -0
- {isar-1.33.4 → isar-1.33.6}/.github/workflows/pythonpackage.yml +0 -0
- {isar-1.33.4 → isar-1.33.6}/.github/workflows/pythonpublish.yml +0 -0
- {isar-1.33.4 → isar-1.33.6}/.github/workflows/stale.yml +0 -0
- {isar-1.33.4 → isar-1.33.6}/.gitignore +0 -0
- {isar-1.33.4 → isar-1.33.6}/.pre-commit-config.yaml +0 -0
- {isar-1.33.4 → isar-1.33.6}/LICENSE +0 -0
- {isar-1.33.4 → isar-1.33.6}/README.md +0 -0
- {isar-1.33.4 → isar-1.33.6}/SECURITY.md +0 -0
- {isar-1.33.4 → isar-1.33.6}/docs/Makefile +0 -0
- {isar-1.33.4 → isar-1.33.6}/docs/full_state_machine_diagram.png +0 -0
- {isar-1.33.4 → isar-1.33.6}/docs/make.bat +0 -0
- {isar-1.33.4 → isar-1.33.6}/docs/mission_state_machine_diagram.png +0 -0
- {isar-1.33.4 → isar-1.33.6}/docs/robot_status_state_machine_diagram.png +0 -0
- {isar-1.33.4 → isar-1.33.6}/docs/rst_processing.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/docs/source/conf.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/docs/source/index.rst +0 -0
- {isar-1.33.4 → isar-1.33.6}/docs/source/readme_link.md +0 -0
- {isar-1.33.4 → isar-1.33.6}/docs/update_state_diagram.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/main.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/pyproject.toml +0 -0
- {isar-1.33.4 → isar-1.33.6}/radixconfig.yml +0 -0
- {isar-1.33.4 → isar-1.33.6}/setup.cfg +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/apis/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/apis/models/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/apis/models/start_mission_definition.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/apis/schedule/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/apis/security/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/apis/security/authentication.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/certs/ca-cert.pem +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/configuration_error.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/keyvault/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/keyvault/keyvault_error.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/keyvault/keyvault_service.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/log.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/logging.conf +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/maps/JSP1_intermediate_deck.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/maps/JSP1_weather_deck.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/maps/default_map.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/maps/klab_b.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/maps/klab_compressor.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/maps/klab_turtlebot.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/maps/turtleworld.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/open_telemetry.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/predefined_mission_definition/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/predefined_mission_definition/default_exr.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/predefined_mission_definition/default_mission.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/predefined_mission_definition/default_turtlebot.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/predefined_missions/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/predefined_missions/default.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/config/predefined_missions/default_turtlebot.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/eventhandlers/eventhandler.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/mission_planner/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/mission_planner/local_planner.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/mission_planner/mission_planner_interface.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/mission_planner/sequential_task_selector.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/mission_planner/task_selector_interface.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/models/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/modules.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/robot/robot_start_mission.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/robot/robot_status.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/robot/robot_task_status.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/script.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/services/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/services/auth/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/services/auth/azure_credentials.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/services/service_connections/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/services/service_connections/mqtt/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/services/service_connections/mqtt/mqtt_client.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/services/service_connections/mqtt/robot_heartbeat_publisher.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/services/service_connections/mqtt/robot_info_publisher.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/services/service_connections/request_handler.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/services/utilities/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/services/utilities/robot_utilities.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/services/utilities/threaded_request.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/states/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/states/blocked_protective_stop.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/states/intervention_needed.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/states/offline.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/states/stopping.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/states/stopping_return_home.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/states/unknown_status.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/transitions/functions/finish_mission.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/transitions/functions/resume.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/transitions/functions/return_home.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/transitions/functions/robot_status.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/transitions/functions/start_mission.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/transitions/functions/stop.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/transitions/functions/utils.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/transitions/robot_status.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/state_machine/utils/common_event_handlers.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/storage/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/storage/blob_storage.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/storage/local_storage.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/storage/storage_interface.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/storage/uploader.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar/storage/utilities.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar.egg-info/dependency_links.txt +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar.egg-info/entry_points.txt +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar.egg-info/requires.txt +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/isar.egg-info/top_level.txt +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/models/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/models/exceptions/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/models/initialize/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/models/inspection/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/models/inspection/inspection.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/models/mission/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/models/mission/mission.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/models/mission/task.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/models/robots/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/models/robots/battery_state.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/models/robots/media.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/models/robots/robot_model.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/robot_interface.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/telemetry/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/telemetry/mqtt_client.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/telemetry/payloads.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/test_robot_interface.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/utilities/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/utilities/json_service.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/src/robot_interface/utilities/uuid_string_factory.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/conftest.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/integration/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/integration/turtlebot/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/integration/turtlebot/config/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/integration/turtlebot/config/maps/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/integration/turtlebot/config/maps/turtleworld.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/integration/turtlebot/config/missions/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/integration/turtlebot/config/missions/default.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/integration/turtlebot/test_successful_mission.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/apis/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/apis/models/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/apis/models/example_mission_definition.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/apis/models/test_start_mission_definition.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/apis/scheduler/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/apis/scheduler/test_scheduler_router.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/apis/security/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/apis/security/test_authentication.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/mission/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/mission/test_mission.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/models/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/models/communication/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/models/communication/test_events.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/services/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/services/readers/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/services/readers/test_mission_reader.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/services/service_connections/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/services/service_connections/echo/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/services/service_connections/test_base_request_handler.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/services/utilities/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/services/utilities/test_queue_utilities.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/services/utilities/test_scheduling_utilities.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/state_machine/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/state_machine/states/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/state_machine/states/test_monitor.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/storage/test_blob_storage.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/isar/storage/test_uploader.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/test_data/test_map_config/test_map_config.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/test_data/test_mission_not_working.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/test_data/test_mission_working.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/test_data/test_mission_working_no_tasks.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/test_data/test_thermal_image_mission.json +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/test_double/__init__.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/test_double/blob_storage.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/test_double/mission_definition.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/test_double/mqtt_client.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/test_double/pose.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/test_double/request.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/test_double/robot_interface.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/test_double/status.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/test_double/task.py +0 -0
- {isar-1.33.4 → isar-1.33.6}/tests/test_double/token.py +0 -0
|
@@ -8,13 +8,13 @@ alitra==1.1.5
|
|
|
8
8
|
# via isar (pyproject.toml)
|
|
9
9
|
annotated-types==0.7.0
|
|
10
10
|
# via pydantic
|
|
11
|
-
anyio==4.
|
|
11
|
+
anyio==4.10.0
|
|
12
12
|
# via
|
|
13
13
|
# httpx
|
|
14
14
|
# starlette
|
|
15
15
|
asgiref==3.9.1
|
|
16
16
|
# via opentelemetry-instrumentation-asgi
|
|
17
|
-
azure-core==1.35.
|
|
17
|
+
azure-core==1.35.1
|
|
18
18
|
# via
|
|
19
19
|
# azure-core-tracing-opentelemetry
|
|
20
20
|
# azure-identity
|
|
@@ -25,15 +25,15 @@ azure-core==1.35.0
|
|
|
25
25
|
# msrest
|
|
26
26
|
azure-core-tracing-opentelemetry==1.0.0b12
|
|
27
27
|
# via azure-monitor-opentelemetry
|
|
28
|
-
azure-identity==1.
|
|
28
|
+
azure-identity==1.25.0
|
|
29
29
|
# via
|
|
30
30
|
# azure-monitor-opentelemetry-exporter
|
|
31
31
|
# isar (pyproject.toml)
|
|
32
32
|
azure-keyvault-secrets==4.10.0
|
|
33
33
|
# via isar (pyproject.toml)
|
|
34
|
-
azure-monitor-opentelemetry==1.6.
|
|
34
|
+
azure-monitor-opentelemetry==1.6.7
|
|
35
35
|
# via isar (pyproject.toml)
|
|
36
|
-
azure-monitor-opentelemetry-exporter==1.0.
|
|
36
|
+
azure-monitor-opentelemetry-exporter==1.0.0b41
|
|
37
37
|
# via
|
|
38
38
|
# azure-monitor-opentelemetry
|
|
39
39
|
# isar (pyproject.toml)
|
|
@@ -41,21 +41,21 @@ azure-storage-blob==12.26.0
|
|
|
41
41
|
# via isar (pyproject.toml)
|
|
42
42
|
backoff==2.2.1
|
|
43
43
|
# via isar (pyproject.toml)
|
|
44
|
-
certifi==2025.
|
|
44
|
+
certifi==2025.8.3
|
|
45
45
|
# via
|
|
46
46
|
# httpcore
|
|
47
47
|
# httpx
|
|
48
48
|
# msrest
|
|
49
49
|
# requests
|
|
50
|
-
cffi==
|
|
50
|
+
cffi==2.0.0
|
|
51
51
|
# via cryptography
|
|
52
|
-
charset-normalizer==3.4.
|
|
52
|
+
charset-normalizer==3.4.3
|
|
53
53
|
# via requests
|
|
54
54
|
click==8.2.1
|
|
55
55
|
# via
|
|
56
56
|
# isar (pyproject.toml)
|
|
57
57
|
# uvicorn
|
|
58
|
-
cryptography==45.0.
|
|
58
|
+
cryptography==45.0.7
|
|
59
59
|
# via
|
|
60
60
|
# azure-identity
|
|
61
61
|
# azure-storage-blob
|
|
@@ -110,14 +110,14 @@ msal-extensions==1.3.1
|
|
|
110
110
|
# via azure-identity
|
|
111
111
|
msrest==0.7.1
|
|
112
112
|
# via azure-monitor-opentelemetry-exporter
|
|
113
|
-
numpy==2.3.
|
|
113
|
+
numpy==2.3.3
|
|
114
114
|
# via
|
|
115
115
|
# alitra
|
|
116
116
|
# isar (pyproject.toml)
|
|
117
117
|
# scipy
|
|
118
118
|
oauthlib==3.3.1
|
|
119
119
|
# via requests-oauthlib
|
|
120
|
-
opentelemetry-api==1.
|
|
120
|
+
opentelemetry-api==1.37.0
|
|
121
121
|
# via
|
|
122
122
|
# azure-core-tracing-opentelemetry
|
|
123
123
|
# azure-monitor-opentelemetry-exporter
|
|
@@ -137,17 +137,17 @@ opentelemetry-api==1.36.0
|
|
|
137
137
|
# opentelemetry-instrumentation-wsgi
|
|
138
138
|
# opentelemetry-sdk
|
|
139
139
|
# opentelemetry-semantic-conventions
|
|
140
|
-
opentelemetry-exporter-otlp==1.
|
|
140
|
+
opentelemetry-exporter-otlp==1.37.0
|
|
141
141
|
# via isar (pyproject.toml)
|
|
142
|
-
opentelemetry-exporter-otlp-proto-common==1.
|
|
142
|
+
opentelemetry-exporter-otlp-proto-common==1.37.0
|
|
143
143
|
# via
|
|
144
144
|
# opentelemetry-exporter-otlp-proto-grpc
|
|
145
145
|
# opentelemetry-exporter-otlp-proto-http
|
|
146
|
-
opentelemetry-exporter-otlp-proto-grpc==1.
|
|
146
|
+
opentelemetry-exporter-otlp-proto-grpc==1.37.0
|
|
147
147
|
# via opentelemetry-exporter-otlp
|
|
148
|
-
opentelemetry-exporter-otlp-proto-http==1.
|
|
148
|
+
opentelemetry-exporter-otlp-proto-http==1.37.0
|
|
149
149
|
# via opentelemetry-exporter-otlp
|
|
150
|
-
opentelemetry-instrumentation==0.
|
|
150
|
+
opentelemetry-instrumentation==0.58b0
|
|
151
151
|
# via
|
|
152
152
|
# opentelemetry-instrumentation-asgi
|
|
153
153
|
# opentelemetry-instrumentation-dbapi
|
|
@@ -159,38 +159,38 @@ opentelemetry-instrumentation==0.57b0
|
|
|
159
159
|
# opentelemetry-instrumentation-urllib
|
|
160
160
|
# opentelemetry-instrumentation-urllib3
|
|
161
161
|
# opentelemetry-instrumentation-wsgi
|
|
162
|
-
opentelemetry-instrumentation-asgi==0.
|
|
162
|
+
opentelemetry-instrumentation-asgi==0.58b0
|
|
163
163
|
# via opentelemetry-instrumentation-fastapi
|
|
164
|
-
opentelemetry-instrumentation-dbapi==0.
|
|
164
|
+
opentelemetry-instrumentation-dbapi==0.58b0
|
|
165
165
|
# via opentelemetry-instrumentation-psycopg2
|
|
166
|
-
opentelemetry-instrumentation-django==0.
|
|
166
|
+
opentelemetry-instrumentation-django==0.58b0
|
|
167
167
|
# via azure-monitor-opentelemetry
|
|
168
|
-
opentelemetry-instrumentation-fastapi==0.
|
|
168
|
+
opentelemetry-instrumentation-fastapi==0.58b0
|
|
169
169
|
# via
|
|
170
170
|
# azure-monitor-opentelemetry
|
|
171
171
|
# isar (pyproject.toml)
|
|
172
|
-
opentelemetry-instrumentation-flask==0.
|
|
172
|
+
opentelemetry-instrumentation-flask==0.58b0
|
|
173
173
|
# via azure-monitor-opentelemetry
|
|
174
|
-
opentelemetry-instrumentation-psycopg2==0.
|
|
174
|
+
opentelemetry-instrumentation-psycopg2==0.58b0
|
|
175
175
|
# via azure-monitor-opentelemetry
|
|
176
|
-
opentelemetry-instrumentation-requests==0.
|
|
176
|
+
opentelemetry-instrumentation-requests==0.58b0
|
|
177
177
|
# via azure-monitor-opentelemetry
|
|
178
|
-
opentelemetry-instrumentation-urllib==0.
|
|
178
|
+
opentelemetry-instrumentation-urllib==0.58b0
|
|
179
179
|
# via azure-monitor-opentelemetry
|
|
180
|
-
opentelemetry-instrumentation-urllib3==0.
|
|
180
|
+
opentelemetry-instrumentation-urllib3==0.58b0
|
|
181
181
|
# via azure-monitor-opentelemetry
|
|
182
|
-
opentelemetry-instrumentation-wsgi==0.
|
|
182
|
+
opentelemetry-instrumentation-wsgi==0.58b0
|
|
183
183
|
# via
|
|
184
184
|
# opentelemetry-instrumentation-django
|
|
185
185
|
# opentelemetry-instrumentation-flask
|
|
186
|
-
opentelemetry-proto==1.
|
|
186
|
+
opentelemetry-proto==1.37.0
|
|
187
187
|
# via
|
|
188
188
|
# opentelemetry-exporter-otlp-proto-common
|
|
189
189
|
# opentelemetry-exporter-otlp-proto-grpc
|
|
190
190
|
# opentelemetry-exporter-otlp-proto-http
|
|
191
191
|
opentelemetry-resource-detector-azure==0.1.5
|
|
192
192
|
# via azure-monitor-opentelemetry
|
|
193
|
-
opentelemetry-sdk==1.
|
|
193
|
+
opentelemetry-sdk==1.37.0
|
|
194
194
|
# via
|
|
195
195
|
# azure-monitor-opentelemetry
|
|
196
196
|
# azure-monitor-opentelemetry-exporter
|
|
@@ -198,7 +198,7 @@ opentelemetry-sdk==1.36.0
|
|
|
198
198
|
# opentelemetry-exporter-otlp-proto-grpc
|
|
199
199
|
# opentelemetry-exporter-otlp-proto-http
|
|
200
200
|
# opentelemetry-resource-detector-azure
|
|
201
|
-
opentelemetry-semantic-conventions==0.
|
|
201
|
+
opentelemetry-semantic-conventions==0.58b0
|
|
202
202
|
# via
|
|
203
203
|
# opentelemetry-instrumentation
|
|
204
204
|
# opentelemetry-instrumentation-asgi
|
|
@@ -211,7 +211,7 @@ opentelemetry-semantic-conventions==0.57b0
|
|
|
211
211
|
# opentelemetry-instrumentation-urllib3
|
|
212
212
|
# opentelemetry-instrumentation-wsgi
|
|
213
213
|
# opentelemetry-sdk
|
|
214
|
-
opentelemetry-util-http==0.
|
|
214
|
+
opentelemetry-util-http==0.58b0
|
|
215
215
|
# via
|
|
216
216
|
# opentelemetry-instrumentation-asgi
|
|
217
217
|
# opentelemetry-instrumentation-django
|
|
@@ -227,15 +227,15 @@ packaging==25.0
|
|
|
227
227
|
# opentelemetry-instrumentation-flask
|
|
228
228
|
paho-mqtt==2.1.0
|
|
229
229
|
# via isar (pyproject.toml)
|
|
230
|
-
protobuf==6.
|
|
230
|
+
protobuf==6.32.1
|
|
231
231
|
# via
|
|
232
232
|
# googleapis-common-protos
|
|
233
233
|
# opentelemetry-proto
|
|
234
234
|
psutil==7.0.0
|
|
235
235
|
# via azure-monitor-opentelemetry-exporter
|
|
236
|
-
pycparser==2.
|
|
236
|
+
pycparser==2.23
|
|
237
237
|
# via cffi
|
|
238
|
-
pydantic==2.11.
|
|
238
|
+
pydantic==2.11.9
|
|
239
239
|
# via
|
|
240
240
|
# fastapi
|
|
241
241
|
# isar (pyproject.toml)
|
|
@@ -255,7 +255,7 @@ python-dotenv==1.1.1
|
|
|
255
255
|
# pydantic-settings
|
|
256
256
|
pyyaml==6.0.2
|
|
257
257
|
# via isar (pyproject.toml)
|
|
258
|
-
requests==2.32.
|
|
258
|
+
requests==2.32.5
|
|
259
259
|
# via
|
|
260
260
|
# azure-core
|
|
261
261
|
# isar (pyproject.toml)
|
|
@@ -268,7 +268,7 @@ requests-oauthlib==2.0.0
|
|
|
268
268
|
# via msrest
|
|
269
269
|
requests-toolbelt==1.0.0
|
|
270
270
|
# via isar (pyproject.toml)
|
|
271
|
-
scipy==1.16.
|
|
271
|
+
scipy==1.16.2
|
|
272
272
|
# via alitra
|
|
273
273
|
six==1.17.0
|
|
274
274
|
# via
|
|
@@ -276,11 +276,11 @@ six==1.17.0
|
|
|
276
276
|
# transitions
|
|
277
277
|
sniffio==1.3.1
|
|
278
278
|
# via anyio
|
|
279
|
-
starlette==0.47.
|
|
279
|
+
starlette==0.47.3
|
|
280
280
|
# via fastapi
|
|
281
281
|
transitions==0.9.3
|
|
282
282
|
# via isar (pyproject.toml)
|
|
283
|
-
typing-extensions==4.
|
|
283
|
+
typing-extensions==4.15.0
|
|
284
284
|
# via
|
|
285
285
|
# azure-core
|
|
286
286
|
# azure-identity
|
|
@@ -303,7 +303,7 @@ urllib3==2.5.0
|
|
|
303
303
|
# via requests
|
|
304
304
|
uvicorn==0.35.0
|
|
305
305
|
# via isar (pyproject.toml)
|
|
306
|
-
wrapt==1.17.
|
|
306
|
+
wrapt==1.17.3
|
|
307
307
|
# via
|
|
308
308
|
# opentelemetry-instrumentation
|
|
309
309
|
# opentelemetry-instrumentation-dbapi
|
|
@@ -245,6 +245,40 @@ class API:
|
|
|
245
245
|
},
|
|
246
246
|
},
|
|
247
247
|
)
|
|
248
|
+
router.add_api_route(
|
|
249
|
+
path="/schedule/lockdown",
|
|
250
|
+
endpoint=self.scheduling_controller.lockdown,
|
|
251
|
+
methods=["POST"],
|
|
252
|
+
dependencies=[authentication_dependency],
|
|
253
|
+
summary="Send the robot to dock and ensure that it stays there",
|
|
254
|
+
responses={
|
|
255
|
+
HTTPStatus.OK.value: {"description": "Robot going to dock"},
|
|
256
|
+
HTTPStatus.CONFLICT.value: {
|
|
257
|
+
"description": "Conflict - Invalid command in the current state"
|
|
258
|
+
},
|
|
259
|
+
HTTPStatus.INTERNAL_SERVER_ERROR.value: {
|
|
260
|
+
"description": "Internal Server Error - Current state of state machine unknown"
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
)
|
|
264
|
+
router.add_api_route(
|
|
265
|
+
path="/schedule/release-lockdown",
|
|
266
|
+
endpoint=self.scheduling_controller.release_lockdown,
|
|
267
|
+
methods=["POST"],
|
|
268
|
+
dependencies=[authentication_dependency],
|
|
269
|
+
summary="Allow the robot to start missions again",
|
|
270
|
+
responses={
|
|
271
|
+
HTTPStatus.OK.value: {
|
|
272
|
+
"description": "Robot is able to receive missions again"
|
|
273
|
+
},
|
|
274
|
+
HTTPStatus.CONFLICT.value: {
|
|
275
|
+
"description": "Conflict - Invalid command in the current state"
|
|
276
|
+
},
|
|
277
|
+
HTTPStatus.INTERNAL_SERVER_ERROR.value: {
|
|
278
|
+
"description": "Internal Server Error - Current state of state machine unknown"
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
)
|
|
248
282
|
router.add_api_route(
|
|
249
283
|
path="/schedule/release-intervention-needed",
|
|
250
284
|
endpoint=self.scheduling_controller.release_intervention_needed,
|
|
@@ -32,6 +32,11 @@ class MissionStartResponse(BaseModel):
|
|
|
32
32
|
mission_not_started_reason: Optional[str] = None
|
|
33
33
|
|
|
34
34
|
|
|
35
|
+
class LockdownResponse(BaseModel):
|
|
36
|
+
lockdown_started: bool
|
|
37
|
+
failure_reason: Optional[str] = None
|
|
38
|
+
|
|
39
|
+
|
|
35
40
|
class RobotInfoResponse(BaseModel):
|
|
36
41
|
robot_package: str
|
|
37
42
|
isar_id: str
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
|
|
3
3
|
from fastapi import HTTPException
|
|
4
|
+
from opentelemetry import trace
|
|
4
5
|
|
|
5
6
|
from isar.apis.models.models import RobotInfoResponse
|
|
6
7
|
from isar.config.settings import robot_settings, settings
|
|
7
8
|
from isar.services.utilities.robot_utilities import RobotUtilities
|
|
8
9
|
from robot_interface.models.robots.media import MediaConfig
|
|
9
10
|
|
|
11
|
+
tracer = trace.get_tracer(__name__)
|
|
12
|
+
|
|
10
13
|
|
|
11
14
|
class RobotController:
|
|
12
15
|
def __init__(
|
|
@@ -16,6 +19,7 @@ class RobotController:
|
|
|
16
19
|
self.robot_utilities: RobotUtilities = robot_utilities
|
|
17
20
|
self.logger = logging.getLogger("api")
|
|
18
21
|
|
|
22
|
+
@tracer.start_as_current_span("generate_media_config")
|
|
19
23
|
def generate_media_config(self) -> MediaConfig:
|
|
20
24
|
media_config: MediaConfig = self.robot_utilities.generate_media_config()
|
|
21
25
|
if media_config is None:
|
|
@@ -25,6 +29,7 @@ class RobotController:
|
|
|
25
29
|
)
|
|
26
30
|
return media_config
|
|
27
31
|
|
|
32
|
+
@tracer.start_as_current_span("get_info")
|
|
28
33
|
def get_info(self) -> RobotInfoResponse:
|
|
29
34
|
return RobotInfoResponse(
|
|
30
35
|
robot_package=settings.ROBOT_PACKAGE,
|
|
@@ -2,6 +2,7 @@ import logging
|
|
|
2
2
|
from http import HTTPStatus
|
|
3
3
|
|
|
4
4
|
from fastapi import Body, HTTPException, Path
|
|
5
|
+
from opentelemetry import trace
|
|
5
6
|
|
|
6
7
|
from isar.apis.models.models import (
|
|
7
8
|
ControlMissionResponse,
|
|
@@ -20,6 +21,8 @@ from isar.state_machine.states_enum import States
|
|
|
20
21
|
from robot_interface.models.mission.mission import Mission
|
|
21
22
|
from robot_interface.models.mission.task import TASKS, InspectionTask, MoveArm
|
|
22
23
|
|
|
24
|
+
tracer = trace.get_tracer(__name__)
|
|
25
|
+
|
|
23
26
|
|
|
24
27
|
class SchedulingController:
|
|
25
28
|
def __init__(
|
|
@@ -29,6 +32,7 @@ class SchedulingController:
|
|
|
29
32
|
self.scheduling_utilities: SchedulingUtilities = scheduling_utilities
|
|
30
33
|
self.logger = logging.getLogger("api")
|
|
31
34
|
|
|
35
|
+
@tracer.start_as_current_span("start_mission_by_id")
|
|
32
36
|
def start_mission_by_id(
|
|
33
37
|
self,
|
|
34
38
|
mission_id: str = Path(
|
|
@@ -54,6 +58,7 @@ class SchedulingController:
|
|
|
54
58
|
|
|
55
59
|
return self._api_response(mission)
|
|
56
60
|
|
|
61
|
+
@tracer.start_as_current_span("start_mission")
|
|
57
62
|
def start_mission(
|
|
58
63
|
self,
|
|
59
64
|
mission_definition: StartMissionDefinition = Body(
|
|
@@ -98,6 +103,7 @@ class SchedulingController:
|
|
|
98
103
|
self.scheduling_utilities.start_mission(mission=mission)
|
|
99
104
|
return self._api_response(mission)
|
|
100
105
|
|
|
106
|
+
@tracer.start_as_current_span("return_home")
|
|
101
107
|
def return_home(self) -> None:
|
|
102
108
|
self.logger.info("Received request to return home")
|
|
103
109
|
|
|
@@ -108,6 +114,7 @@ class SchedulingController:
|
|
|
108
114
|
|
|
109
115
|
self.scheduling_utilities.return_home()
|
|
110
116
|
|
|
117
|
+
@tracer.start_as_current_span("pause_mission")
|
|
111
118
|
def pause_mission(self) -> ControlMissionResponse:
|
|
112
119
|
self.logger.info("Received request to pause current mission")
|
|
113
120
|
|
|
@@ -131,6 +138,7 @@ class SchedulingController:
|
|
|
131
138
|
)
|
|
132
139
|
return pause_mission_response
|
|
133
140
|
|
|
141
|
+
@tracer.start_as_current_span("resume_mission")
|
|
134
142
|
def resume_mission(self) -> ControlMissionResponse:
|
|
135
143
|
self.logger.info("Received request to resume current mission")
|
|
136
144
|
|
|
@@ -148,6 +156,7 @@ class SchedulingController:
|
|
|
148
156
|
)
|
|
149
157
|
return resume_mission_response
|
|
150
158
|
|
|
159
|
+
@tracer.start_as_current_span("stop_mission")
|
|
151
160
|
def stop_mission(
|
|
152
161
|
self,
|
|
153
162
|
mission_id: StopMissionDefinition = Body(
|
|
@@ -181,6 +190,7 @@ class SchedulingController:
|
|
|
181
190
|
)
|
|
182
191
|
return stop_mission_response
|
|
183
192
|
|
|
193
|
+
@tracer.start_as_current_span("start_move_arm_mission")
|
|
184
194
|
def start_move_arm_mission(
|
|
185
195
|
self,
|
|
186
196
|
arm_pose_literal: str = Path(
|
|
@@ -227,6 +237,7 @@ class SchedulingController:
|
|
|
227
237
|
self.scheduling_utilities.start_mission(mission=mission)
|
|
228
238
|
return self._api_response(mission)
|
|
229
239
|
|
|
240
|
+
@tracer.start_as_current_span("release_intervention_needed")
|
|
230
241
|
def release_intervention_needed(self) -> None:
|
|
231
242
|
self.logger.info("Received request to release intervention needed state")
|
|
232
243
|
|
|
@@ -243,6 +254,40 @@ class SchedulingController:
|
|
|
243
254
|
self.scheduling_utilities.release_intervention_needed()
|
|
244
255
|
self.logger.info("Released intervention needed state successfully")
|
|
245
256
|
|
|
257
|
+
@tracer.start_as_current_span("lockdown")
|
|
258
|
+
def lockdown(self) -> None:
|
|
259
|
+
self.logger.info("Received request to lockdown robot")
|
|
260
|
+
|
|
261
|
+
state: States = self.scheduling_utilities.get_state()
|
|
262
|
+
|
|
263
|
+
if state == States.Lockdown:
|
|
264
|
+
error_message = "Conflict - Lockdown command received in lockdown state"
|
|
265
|
+
self.logger.warning(error_message)
|
|
266
|
+
raise HTTPException(
|
|
267
|
+
status_code=HTTPStatus.CONFLICT,
|
|
268
|
+
detail=error_message,
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
self.scheduling_utilities.lock_down_robot()
|
|
272
|
+
self.logger.info("Lockdown started successfully")
|
|
273
|
+
|
|
274
|
+
@tracer.start_as_current_span("release_lockdown")
|
|
275
|
+
def release_lockdown(self) -> None:
|
|
276
|
+
self.logger.info("Received request to release robot lockdown")
|
|
277
|
+
|
|
278
|
+
state: States = self.scheduling_utilities.get_state()
|
|
279
|
+
|
|
280
|
+
if state != States.Lockdown:
|
|
281
|
+
error_message = f"Conflict - Release lockdown command received in invalid state - State: {state}"
|
|
282
|
+
self.logger.warning(error_message)
|
|
283
|
+
raise HTTPException(
|
|
284
|
+
status_code=HTTPStatus.CONFLICT,
|
|
285
|
+
detail=error_message,
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
self.scheduling_utilities.release_robot_lockdown()
|
|
289
|
+
self.logger.info("Released lockdown successfully")
|
|
290
|
+
|
|
246
291
|
def _api_response(self, mission: Mission) -> StartMissionResponse:
|
|
247
292
|
return StartMissionResponse(
|
|
248
293
|
id=mission.id,
|
|
@@ -30,7 +30,7 @@ class Settings(BaseSettings):
|
|
|
30
30
|
REQUEST_TIMEOUT: int = Field(default=30)
|
|
31
31
|
|
|
32
32
|
# Timeout in seconds for checking whether there is a message on a queue
|
|
33
|
-
QUEUE_TIMEOUT: int = Field(default=
|
|
33
|
+
QUEUE_TIMEOUT: int = Field(default=10)
|
|
34
34
|
|
|
35
35
|
# Sleep time for while loops in the finite state machine in seconds
|
|
36
36
|
# The sleep is used to throttle the system on every iteration in the loop
|
|
@@ -4,7 +4,11 @@ from typing import Generic, Optional, TypeVar
|
|
|
4
4
|
|
|
5
5
|
from transitions import State
|
|
6
6
|
|
|
7
|
-
from isar.apis.models.models import
|
|
7
|
+
from isar.apis.models.models import (
|
|
8
|
+
ControlMissionResponse,
|
|
9
|
+
LockdownResponse,
|
|
10
|
+
MissionStartResponse,
|
|
11
|
+
)
|
|
8
12
|
from isar.config.settings import settings
|
|
9
13
|
from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
|
|
10
14
|
from robot_interface.models.mission.mission import Mission
|
|
@@ -105,6 +109,12 @@ class APIRequests:
|
|
|
105
109
|
self.release_intervention_needed: APIEvent[bool, bool] = APIEvent(
|
|
106
110
|
"release_intervention_needed"
|
|
107
111
|
)
|
|
112
|
+
self.send_to_lockdown: APIEvent[bool, LockdownResponse] = APIEvent(
|
|
113
|
+
"send_to_lockdown"
|
|
114
|
+
)
|
|
115
|
+
self.release_from_lockdown: APIEvent[bool, bool] = APIEvent(
|
|
116
|
+
"release_from_lockdown"
|
|
117
|
+
)
|
|
108
118
|
|
|
109
119
|
|
|
110
120
|
class StateMachineEvents:
|
|
@@ -128,6 +138,12 @@ class RobotServiceEvents:
|
|
|
128
138
|
self.mission_successfully_stopped: Event[bool] = Event(
|
|
129
139
|
"mission_successfully_stopped"
|
|
130
140
|
)
|
|
141
|
+
self.mission_failed_to_pause: Event[ErrorMessage] = Event(
|
|
142
|
+
"mission_failed_to_pause"
|
|
143
|
+
)
|
|
144
|
+
self.mission_successfully_paused: Event[bool] = Event(
|
|
145
|
+
"mission_successfully_paused"
|
|
146
|
+
)
|
|
131
147
|
|
|
132
148
|
|
|
133
149
|
class SharedState:
|
|
@@ -9,6 +9,7 @@ from isar.models.events import (
|
|
|
9
9
|
SharedState,
|
|
10
10
|
StateMachineEvents,
|
|
11
11
|
)
|
|
12
|
+
from isar.robot.robot_pause_mission import RobotPauseMissionThread
|
|
12
13
|
from isar.robot.robot_start_mission import RobotStartMissionThread
|
|
13
14
|
from isar.robot.robot_status import RobotStatusThread
|
|
14
15
|
from isar.robot.robot_stop_mission import RobotStopMissionThread
|
|
@@ -31,6 +32,7 @@ class Robot(object):
|
|
|
31
32
|
self.robot_status_thread: Optional[RobotStatusThread] = None
|
|
32
33
|
self.robot_task_status_thread: Optional[RobotTaskStatusThread] = None
|
|
33
34
|
self.stop_mission_thread: Optional[RobotStopMissionThread] = None
|
|
35
|
+
self.pause_mission_thread: Optional[RobotPauseMissionThread] = None
|
|
34
36
|
self.signal_thread_quitting: ThreadEvent = ThreadEvent()
|
|
35
37
|
|
|
36
38
|
def stop(self) -> None:
|
|
@@ -111,6 +113,34 @@ class Robot(object):
|
|
|
111
113
|
)
|
|
112
114
|
self.stop_mission_thread.start()
|
|
113
115
|
|
|
116
|
+
def _pause_mission_request_handler(self, event: Event[bool]) -> None:
|
|
117
|
+
if event.consume_event():
|
|
118
|
+
if (
|
|
119
|
+
self.pause_mission_thread is not None
|
|
120
|
+
and self.pause_mission_thread.is_alive()
|
|
121
|
+
):
|
|
122
|
+
self.logger.warning(
|
|
123
|
+
"Received pause mission event while trying to pause a mission. Aborting pause attempt."
|
|
124
|
+
)
|
|
125
|
+
return
|
|
126
|
+
if (
|
|
127
|
+
self.start_mission_thread is not None
|
|
128
|
+
and self.start_mission_thread.is_alive()
|
|
129
|
+
):
|
|
130
|
+
error_description = "Received pause mission event while trying to start a mission. Aborting pause attempt."
|
|
131
|
+
error_message = ErrorMessage(
|
|
132
|
+
error_reason=ErrorReason.RobotStillStartingMissionException,
|
|
133
|
+
error_description=error_description,
|
|
134
|
+
)
|
|
135
|
+
self.robot_service_events.mission_failed_to_stop.trigger_event(
|
|
136
|
+
error_message
|
|
137
|
+
)
|
|
138
|
+
return
|
|
139
|
+
self.pause_mission_thread = RobotPauseMissionThread(
|
|
140
|
+
self.robot_service_events, self.robot, self.signal_thread_quitting
|
|
141
|
+
)
|
|
142
|
+
self.pause_mission_thread.start()
|
|
143
|
+
|
|
114
144
|
def run(self) -> None:
|
|
115
145
|
self.robot_status_thread = RobotStatusThread(
|
|
116
146
|
self.robot, self.signal_thread_quitting, self.shared_state
|
|
@@ -124,6 +154,8 @@ class Robot(object):
|
|
|
124
154
|
self.state_machine_events.task_status_request
|
|
125
155
|
)
|
|
126
156
|
|
|
157
|
+
self._pause_mission_request_handler(self.state_machine_events.pause_mission)
|
|
158
|
+
|
|
127
159
|
self._stop_mission_request_handler(self.state_machine_events.stop_mission)
|
|
128
160
|
|
|
129
161
|
self.logger.info("Exiting robot service main thread")
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import time
|
|
3
|
+
from threading import Event, Thread
|
|
4
|
+
from typing import Optional
|
|
5
|
+
|
|
6
|
+
from isar.config.settings import settings
|
|
7
|
+
from isar.models.events import RobotServiceEvents
|
|
8
|
+
from robot_interface.models.exceptions.robot_exceptions import (
|
|
9
|
+
ErrorMessage,
|
|
10
|
+
RobotActionException,
|
|
11
|
+
RobotException,
|
|
12
|
+
)
|
|
13
|
+
from robot_interface.robot_interface import RobotInterface
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class RobotPauseMissionThread(Thread):
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
robot_service_events: RobotServiceEvents,
|
|
20
|
+
robot: RobotInterface,
|
|
21
|
+
signal_thread_quitting: Event,
|
|
22
|
+
):
|
|
23
|
+
self.logger = logging.getLogger("robot")
|
|
24
|
+
self.robot_service_events: RobotServiceEvents = robot_service_events
|
|
25
|
+
self.robot: RobotInterface = robot
|
|
26
|
+
self.signal_thread_quitting: Event = signal_thread_quitting
|
|
27
|
+
Thread.__init__(self, name="Robot pause mission thread")
|
|
28
|
+
|
|
29
|
+
def run(self) -> None:
|
|
30
|
+
retries = 0
|
|
31
|
+
error: Optional[ErrorMessage] = None
|
|
32
|
+
while retries < settings.STATE_TRANSITION_NUM_RETIRES:
|
|
33
|
+
if self.signal_thread_quitting.wait(0):
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
self.robot.pause()
|
|
38
|
+
except (RobotActionException, RobotException) as e:
|
|
39
|
+
self.logger.warning(
|
|
40
|
+
f"\nFailed to pause robot because: {e.error_description}"
|
|
41
|
+
f"\nAttempting to pause the robot again"
|
|
42
|
+
)
|
|
43
|
+
retries += 1
|
|
44
|
+
error = ErrorMessage(
|
|
45
|
+
error_reason=e.error_reason, error_description=e.error_description
|
|
46
|
+
)
|
|
47
|
+
time.sleep(settings.FSM_SLEEP_TIME)
|
|
48
|
+
continue
|
|
49
|
+
self.robot_service_events.mission_successfully_paused.trigger_event(True)
|
|
50
|
+
return
|
|
51
|
+
|
|
52
|
+
error_description = (
|
|
53
|
+
f"\nFailed to pause the robot after {retries} attempts because: "
|
|
54
|
+
f"{error.error_description}"
|
|
55
|
+
f"\nBe aware that the robot may still be moving even though a pause has "
|
|
56
|
+
"been attempted"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
error_message = ErrorMessage(
|
|
60
|
+
error_reason=error.error_reason,
|
|
61
|
+
error_description=error_description,
|
|
62
|
+
)
|
|
63
|
+
self.robot_service_events.mission_failed_to_pause.trigger_event(error_message)
|
|
@@ -24,7 +24,7 @@ class RobotStopMissionThread(Thread):
|
|
|
24
24
|
self.robot_service_events: RobotServiceEvents = robot_service_events
|
|
25
25
|
self.robot: RobotInterface = robot
|
|
26
26
|
self.signal_thread_quitting: Event = signal_thread_quitting
|
|
27
|
-
Thread.__init__(self, name="Robot
|
|
27
|
+
Thread.__init__(self, name="Robot stop mission thread")
|
|
28
28
|
|
|
29
29
|
def run(self) -> None:
|
|
30
30
|
retries = 0
|