isar 1.20.2__py3-none-any.whl → 1.34.13__py3-none-any.whl

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.
Files changed (134) hide show
  1. isar/apis/api.py +135 -86
  2. isar/apis/models/__init__.py +0 -1
  3. isar/apis/models/models.py +21 -11
  4. isar/apis/models/start_mission_definition.py +115 -170
  5. isar/apis/robot_control/robot_controller.py +41 -0
  6. isar/apis/schedule/scheduling_controller.py +123 -187
  7. isar/apis/security/authentication.py +5 -5
  8. isar/config/certs/ca-cert.pem +33 -31
  9. isar/config/keyvault/keyvault_service.py +4 -2
  10. isar/config/log.py +45 -40
  11. isar/config/logging.conf +16 -31
  12. isar/config/open_telemetry.py +102 -0
  13. isar/config/settings.py +74 -117
  14. isar/eventhandlers/eventhandler.py +123 -0
  15. isar/models/events.py +184 -0
  16. isar/models/status.py +22 -0
  17. isar/modules.py +117 -200
  18. isar/robot/robot.py +383 -0
  19. isar/robot/robot_battery.py +60 -0
  20. isar/robot/robot_monitor_mission.py +357 -0
  21. isar/robot/robot_pause_mission.py +74 -0
  22. isar/robot/robot_resume_mission.py +67 -0
  23. isar/robot/robot_start_mission.py +66 -0
  24. isar/robot/robot_status.py +61 -0
  25. isar/robot/robot_stop_mission.py +68 -0
  26. isar/robot/robot_upload_inspection.py +75 -0
  27. isar/script.py +58 -41
  28. isar/services/service_connections/mqtt/mqtt_client.py +47 -11
  29. isar/services/service_connections/mqtt/robot_heartbeat_publisher.py +5 -2
  30. isar/services/service_connections/mqtt/robot_info_publisher.py +3 -3
  31. isar/services/service_connections/persistent_memory.py +69 -0
  32. isar/services/utilities/mqtt_utilities.py +93 -0
  33. isar/services/utilities/robot_utilities.py +20 -0
  34. isar/services/utilities/scheduling_utilities.py +386 -100
  35. isar/state_machine/state_machine.py +242 -539
  36. isar/state_machine/states/__init__.py +0 -8
  37. isar/state_machine/states/await_next_mission.py +114 -0
  38. isar/state_machine/states/blocked_protective_stop.py +60 -0
  39. isar/state_machine/states/going_to_lockdown.py +95 -0
  40. isar/state_machine/states/going_to_recharging.py +92 -0
  41. isar/state_machine/states/home.py +115 -0
  42. isar/state_machine/states/intervention_needed.py +77 -0
  43. isar/state_machine/states/lockdown.py +38 -0
  44. isar/state_machine/states/maintenance.py +43 -0
  45. isar/state_machine/states/monitor.py +137 -247
  46. isar/state_machine/states/offline.py +51 -53
  47. isar/state_machine/states/paused.py +92 -23
  48. isar/state_machine/states/pausing.py +48 -0
  49. isar/state_machine/states/pausing_return_home.py +48 -0
  50. isar/state_machine/states/recharging.py +80 -0
  51. isar/state_machine/states/resuming.py +57 -0
  52. isar/state_machine/states/resuming_return_home.py +64 -0
  53. isar/state_machine/states/return_home_paused.py +109 -0
  54. isar/state_machine/states/returning_home.py +217 -0
  55. isar/state_machine/states/stopping.py +69 -0
  56. isar/state_machine/states/stopping_due_to_maintenance.py +61 -0
  57. isar/state_machine/states/stopping_go_to_lockdown.py +60 -0
  58. isar/state_machine/states/stopping_go_to_recharge.py +51 -0
  59. isar/state_machine/states/stopping_paused_mission.py +36 -0
  60. isar/state_machine/states/stopping_paused_return_home.py +59 -0
  61. isar/state_machine/states/stopping_return_home.py +59 -0
  62. isar/state_machine/states/unknown_status.py +74 -0
  63. isar/state_machine/states_enum.py +23 -5
  64. isar/state_machine/transitions/mission.py +225 -0
  65. isar/state_machine/transitions/return_home.py +108 -0
  66. isar/state_machine/transitions/robot_status.py +87 -0
  67. isar/state_machine/utils/common_event_handlers.py +138 -0
  68. isar/storage/blob_storage.py +70 -52
  69. isar/storage/local_storage.py +25 -12
  70. isar/storage/storage_interface.py +28 -7
  71. isar/storage/uploader.py +174 -55
  72. isar/storage/utilities.py +32 -29
  73. {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/METADATA +119 -123
  74. isar-1.34.13.dist-info/RECORD +120 -0
  75. {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/WHEEL +1 -1
  76. {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/entry_points.txt +1 -0
  77. robot_interface/models/exceptions/robot_exceptions.py +91 -41
  78. robot_interface/models/inspection/__init__.py +0 -13
  79. robot_interface/models/inspection/inspection.py +42 -33
  80. robot_interface/models/mission/mission.py +14 -15
  81. robot_interface/models/mission/status.py +20 -26
  82. robot_interface/models/mission/task.py +154 -121
  83. robot_interface/models/robots/battery_state.py +6 -0
  84. robot_interface/models/robots/media.py +13 -0
  85. robot_interface/models/robots/robot_model.py +7 -7
  86. robot_interface/robot_interface.py +119 -84
  87. robot_interface/telemetry/mqtt_client.py +74 -12
  88. robot_interface/telemetry/payloads.py +91 -13
  89. robot_interface/utilities/json_service.py +7 -1
  90. isar/config/configuration_error.py +0 -2
  91. isar/config/keyvault/keyvault_error.py +0 -2
  92. isar/config/predefined_mission_definition/__init__.py +0 -0
  93. isar/config/predefined_mission_definition/default_exr.json +0 -51
  94. isar/config/predefined_mission_definition/default_mission.json +0 -91
  95. isar/config/predefined_mission_definition/default_turtlebot.json +0 -124
  96. isar/config/predefined_missions/__init__.py +0 -0
  97. isar/config/predefined_missions/default.json +0 -92
  98. isar/config/predefined_missions/default_turtlebot.json +0 -110
  99. isar/config/predefined_poses/__init__.py +0 -0
  100. isar/config/predefined_poses/predefined_poses.py +0 -616
  101. isar/config/settings.env +0 -25
  102. isar/mission_planner/__init__.py +0 -0
  103. isar/mission_planner/local_planner.py +0 -82
  104. isar/mission_planner/mission_planner_interface.py +0 -26
  105. isar/mission_planner/sequential_task_selector.py +0 -23
  106. isar/mission_planner/task_selector_interface.py +0 -31
  107. isar/models/communication/__init__.py +0 -0
  108. isar/models/communication/message.py +0 -12
  109. isar/models/communication/queues/__init__.py +0 -4
  110. isar/models/communication/queues/queue_io.py +0 -12
  111. isar/models/communication/queues/queue_timeout_error.py +0 -2
  112. isar/models/communication/queues/queues.py +0 -19
  113. isar/models/communication/queues/status_queue.py +0 -20
  114. isar/models/mission_metadata/__init__.py +0 -0
  115. isar/services/auth/__init__.py +0 -0
  116. isar/services/auth/azure_credentials.py +0 -14
  117. isar/services/readers/__init__.py +0 -0
  118. isar/services/readers/base_reader.py +0 -37
  119. isar/services/service_connections/request_handler.py +0 -153
  120. isar/services/service_connections/stid/__init__.py +0 -0
  121. isar/services/utilities/queue_utilities.py +0 -39
  122. isar/services/utilities/threaded_request.py +0 -68
  123. isar/state_machine/states/idle.py +0 -85
  124. isar/state_machine/states/initialize.py +0 -71
  125. isar/state_machine/states/initiate.py +0 -142
  126. isar/state_machine/states/off.py +0 -18
  127. isar/state_machine/states/stop.py +0 -95
  128. isar/storage/slimm_storage.py +0 -191
  129. isar-1.20.2.dist-info/RECORD +0 -116
  130. robot_interface/models/initialize/__init__.py +0 -1
  131. robot_interface/models/initialize/initialize_params.py +0 -9
  132. robot_interface/models/mission/step.py +0 -234
  133. {isar-1.20.2.dist-info → isar-1.34.13.dist-info/licenses}/LICENSE +0 -0
  134. {isar-1.20.2.dist-info → isar-1.34.13.dist-info}/top_level.txt +0 -0
isar/storage/utilities.py CHANGED
@@ -1,6 +1,5 @@
1
1
  import json
2
- import time
3
- from datetime import UTC, datetime
2
+ from datetime import datetime, timezone
4
3
  from pathlib import Path
5
4
  from typing import Tuple
6
5
 
@@ -34,34 +33,34 @@ def construct_metadata_file(
34
33
  "plant_code": settings.PLANT_CODE,
35
34
  "media_orientation_reference_system": settings.MEDIA_ORIENTATION_REFERENCE_SYSTEM, # noqa: E501
36
35
  "additional_meta": {
36
+ "inspection_id": inspection.id,
37
37
  "mission_id": mission.id,
38
38
  "mission_name": mission.name,
39
+ "mission_date": datetime.now(timezone.utc).date(),
39
40
  "plant_name": settings.PLANT_NAME,
40
- "mission_date": datetime.now(UTC).date(),
41
41
  "isar_id": settings.ISAR_ID,
42
42
  "robot_name": settings.ROBOT_NAME,
43
- "analysis_type": (
44
- inspection.metadata.additional["analysis_type"]
45
- if inspection.metadata.additional
46
- else "N/A"
47
- ),
43
+ "inspection_description": inspection.metadata.inspection_description,
44
+ "tag": inspection.metadata.tag_id,
45
+ "robot_pose": {
46
+ "position": {
47
+ "x": inspection.metadata.robot_pose.position.x,
48
+ "y": inspection.metadata.robot_pose.position.y,
49
+ "z": inspection.metadata.robot_pose.position.z,
50
+ },
51
+ "orientation": inspection.metadata.robot_pose.orientation.to_quat_array(),
52
+ },
53
+ "target_position": {
54
+ "x": inspection.metadata.target_position.x,
55
+ "y": inspection.metadata.target_position.y,
56
+ "z": inspection.metadata.target_position.z,
57
+ },
58
+ "timestamp": inspection.metadata.start_time,
48
59
  },
49
- "data": [
60
+ "data_files": [
50
61
  {
51
62
  "folder": f"/{get_foldername(mission=mission)}",
52
- "files": [
53
- {
54
- "file_name": filename,
55
- "timestamp": inspection.metadata.start_time,
56
- "x": inspection.metadata.pose.position.x,
57
- "y": inspection.metadata.pose.position.y,
58
- "z": inspection.metadata.pose.position.z,
59
- "tag": inspection.metadata.tag_id,
60
- "additional_media_metadata": {
61
- "orientation": inspection.metadata.pose.orientation.to_quat_array() # noqa: E501
62
- },
63
- }
64
- ],
63
+ "file_name": filename,
65
64
  }
66
65
  ],
67
66
  }
@@ -69,15 +68,19 @@ def construct_metadata_file(
69
68
  return json.dumps(data, cls=EnhancedJSONEncoder, indent=4).encode()
70
69
 
71
70
 
72
- def get_filename(
73
- inspection: Inspection,
74
- ) -> str:
75
- inspection_type: str = type(inspection).__name__
71
+ def get_filename(inspection: Inspection) -> str:
72
+ utc_time: str = datetime.now(timezone.utc).strftime("%Y%m%d-%H%M%S")
76
73
  tag: str = inspection.metadata.tag_id if inspection.metadata.tag_id else "no-tag"
77
- epoch_time: int = int(time.time())
78
- return f"{tag}__{inspection_type}__{epoch_time}"
74
+ inspection_type: str = type(inspection).__name__
75
+ inspection_description: str = (
76
+ inspection.metadata.inspection_description.replace(" ", "-")
77
+ if inspection.metadata.inspection_description
78
+ else "NA"
79
+ )
80
+ return f"{tag}__{inspection_type}__{inspection_description}__{utc_time}"
79
81
 
80
82
 
81
83
  def get_foldername(mission: Mission) -> str:
84
+ utc_date: str = datetime.now(timezone.utc).strftime("%Y-%m-%d")
82
85
  mission_name: str = mission.name.replace(" ", "-")
83
- return f"{datetime.now(UTC).date()}__{settings.PLANT_SHORT_NAME}__{mission_name}__{mission.id}"
86
+ return f"{utc_date}__{settings.PLANT_SHORT_NAME}__{mission_name}__{mission.id}"
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: isar
3
- Version: 1.20.2
3
+ Version: 1.34.13
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
@@ -91,15 +91,18 @@ Classifier: Intended Audience :: Science/Research
91
91
  Classifier: License :: OSI Approved :: Eclipse Public License 2.0 (EPL-2.0)
92
92
  Classifier: Natural Language :: English
93
93
  Classifier: Programming Language :: Python :: 3
94
+ Classifier: Programming Language :: Python :: 3.9
95
+ Classifier: Programming Language :: Python :: 3.10
94
96
  Classifier: Programming Language :: Python :: 3.11
95
97
  Classifier: Programming Language :: Python :: 3.12
98
+ Classifier: Programming Language :: Python :: 3.13
96
99
  Classifier: Topic :: Scientific/Engineering
97
100
  Classifier: Topic :: Scientific/Engineering :: Physics
98
101
  Classifier: Topic :: Software Development :: Libraries
99
- Requires-Python: >=3.11
102
+ Requires-Python: >=3.9
100
103
  Description-Content-Type: text/markdown
101
104
  License-File: LICENSE
102
- Requires-Dist: alitra >=1.1.3
105
+ Requires-Dist: alitra>=1.1.3
103
106
  Requires-Dist: azure-identity
104
107
  Requires-Dist: azure-keyvault-secrets
105
108
  Requires-Dist: azure-storage-blob
@@ -107,35 +110,43 @@ Requires-Dist: backoff
107
110
  Requires-Dist: click
108
111
  Requires-Dist: dacite
109
112
  Requires-Dist: fastapi-azure-auth
110
- Requires-Dist: fastapi
111
- Requires-Dist: injector
113
+ Requires-Dist: fastapi>=0.121.0
114
+ Requires-Dist: dependency-injector
112
115
  Requires-Dist: numpy
113
- Requires-Dist: opencensus-ext-azure
114
- Requires-Dist: opencensus-ext-logging
115
- Requires-Dist: opencensus-ext-requests
116
116
  Requires-Dist: paho-mqtt
117
- Requires-Dist: pydantic-settings
117
+ Requires-Dist: pydantic_settings
118
118
  Requires-Dist: pydantic
119
119
  Requires-Dist: PyJWT
120
120
  Requires-Dist: python-dotenv
121
121
  Requires-Dist: PyYAML
122
122
  Requires-Dist: requests-toolbelt
123
123
  Requires-Dist: requests
124
+ Requires-Dist: starlette>=0.49.1
124
125
  Requires-Dist: transitions
125
126
  Requires-Dist: uvicorn
127
+ Requires-Dist: opentelemetry-api==1.38.0
128
+ Requires-Dist: opentelemetry-sdk
129
+ Requires-Dist: opentelemetry-exporter-otlp
130
+ Requires-Dist: opentelemetry-instrumentation-fastapi
131
+ Requires-Dist: azure-monitor-opentelemetry
132
+ Requires-Dist: azure-monitor-opentelemetry-exporter
133
+ Requires-Dist: pymysql
134
+ Requires-Dist: sqlalchemy
135
+ Requires-Dist: psycopg2-binary
126
136
  Provides-Extra: dev
127
- Requires-Dist: black ; extra == 'dev'
128
- Requires-Dist: flake8 ; extra == 'dev'
129
- Requires-Dist: mypy ; extra == 'dev'
130
- Requires-Dist: myst-parser ; extra == 'dev'
131
- Requires-Dist: pip-tools ; extra == 'dev'
132
- Requires-Dist: pre-commit ; extra == 'dev'
133
- Requires-Dist: pytest-dotenv ; extra == 'dev'
134
- Requires-Dist: pytest-mock ; extra == 'dev'
135
- Requires-Dist: pytest-xdist ; extra == 'dev'
136
- Requires-Dist: pytest ; extra == 'dev'
137
- Requires-Dist: requests-mock ; extra == 'dev'
138
- Requires-Dist: sphinx ; extra == 'dev'
137
+ Requires-Dist: black; extra == "dev"
138
+ Requires-Dist: isort; extra == "dev"
139
+ Requires-Dist: mypy; extra == "dev"
140
+ Requires-Dist: pip-tools; extra == "dev"
141
+ Requires-Dist: pre-commit; extra == "dev"
142
+ Requires-Dist: pytest-mock; extra == "dev"
143
+ Requires-Dist: pytest-xdist; extra == "dev"
144
+ Requires-Dist: pytest; extra == "dev"
145
+ Requires-Dist: requests-mock; extra == "dev"
146
+ Requires-Dist: ruff; extra == "dev"
147
+ Requires-Dist: testcontainers[mysql]; extra == "dev"
148
+ Requires-Dist: alembic; extra == "dev"
149
+ Dynamic: license-file
139
150
 
140
151
  # ISAR
141
152
 
@@ -228,12 +239,21 @@ ISAR_ROBOT_PACKAGE = isar_turtlebot
228
239
  ISAR_DEFAULT_MAP = turtleworld
229
240
  ```
230
241
 
242
+ ### Run with make
243
+ Common commands for the project are in [Makefile](./Makefile).
244
+ This requires the CLI program `make`.
245
+
246
+ Usage:
247
+ ```bash
248
+ make <command-in-makefile> # for example: make run
249
+ ```
250
+
231
251
  ### Run ISAR server
232
252
 
233
253
  To run ISAR:
234
254
 
235
255
  ```bash
236
- python main.py
256
+ isar-start
237
257
  ```
238
258
 
239
259
  Note, running the full system requires that an implementation of a robot has been installed. See
@@ -247,32 +267,56 @@ Once the application has been started the swagger site may be accessed at
247
267
  http://localhost:3000/docs
248
268
  ```
249
269
 
250
- Execute the `/schedule/start-mission` endpoint with `mission_id=1` to run a mission.
251
-
252
- In [this](./src/isar/config/predefined_missions) folder there are predefined default missions, for example the mission
253
- corresponding to `mission_id=1`. A new mission may be added by adding a new json-file with a mission description. Note,
254
- the mission IDs must be unique.
255
-
256
- ### Running with docker-compose
257
-
258
- ISAR may be started with an instance of the [isar-robot](https://github.com/equinor/isar-robot) package by
259
-
260
- ```shell
261
- docker-compose up --build
262
- ```
263
-
264
- Provided that the simulator from [isar-turtlebot](https://github.com/equinor/isar-turtlebot) is running ISAR may be
265
- started with the turtlebot by
266
-
267
- ```shell
268
- docker-compose -f docker-compose-turtlebot.yml up --build
269
- ```
270
+ Execute the `/schedule/start-mission` endpoint with the 'mission_definition' value in the body containing a JSON representing a mission definition (see `StartMissionDefinition` in [start_mission_definition.py](./src/isar/apis/models/start_mission_definition.py)).
271
+
272
+ Here is an example body:
273
+ {
274
+ 'mission_definition': {
275
+ 'id': 'example ID',
276
+ 'tasks': [
277
+ {
278
+ 'id': 'example ID',
279
+ 'type': 'inspection',
280
+ 'pose': {
281
+ 'position': {
282
+ 'x': 1.0,
283
+ 'y': 1.0,
284
+ 'z': 1.0,
285
+ 'frame_name': 'robot'
286
+ },
287
+ 'orientation': {
288
+ 'x': 0.0,
289
+ 'y': 0.0,
290
+ 'z': 0.0,
291
+ 'w': 0.0,
292
+ 'frame_name': 'robot'
293
+ },
294
+ 'frame_name': 'robot'
295
+ },
296
+ 'inspection': {
297
+ 'type': 'Image',
298
+ 'inspection_target': {
299
+ 'x': 5.0,
300
+ 'y': 5.0,
301
+ 'z': 5.0,
302
+ 'frame_name': 'robot'
303
+ },
304
+ 'inspection_description': 'Example description,
305
+ 'duration': None
306
+ },
307
+ 'tag': 'example_tag',
308
+ 'zoom': None
309
+ }
310
+ ],
311
+ 'name': 'Example name',
312
+ 'start_pose': None
313
+ }
314
+ }
270
315
 
271
316
  ### Configuration
272
317
 
273
318
  The system consists of many configuration variables which may alter the functionality. As an example, it is possible to
274
- change mission planners or add multiple storage handlers as described in the [mission planner](#mission-planner)
275
- and [storage](#storage) sections.
319
+ add multiple storage handlers as described in the [storage](#storage) section.
276
320
 
277
321
  There are two methods of specifying configuration.
278
322
 
@@ -293,6 +337,20 @@ There are two methods of specifying configuration.
293
337
  By adding environment variables with the prefix `ISAR_` to the [settings.env](./src/isar/config/settings.env) file
294
338
  the configuration variables will be overwritten by the values in this file.
295
339
 
340
+ ### Setup for testing
341
+ To be able to execute the tests you need to set the `ISAR_ENV` environment variable beforehand. Depending on your operating system and the command line you are using you can use one of the following commands:
342
+
343
+ **Bash/Zsh**
344
+ ```bash
345
+ export ISAR_ENV=test
346
+ ```
347
+ **Windows Command prompt**
348
+ ```cmd
349
+ set ISAR_ENV=test
350
+ ```
351
+
352
+ Remember to set `ISAR_ENV` back to `None` when you want to run `isar-start` afterwards.
353
+
296
354
  ### Running tests
297
355
 
298
356
  After following the steps in [Development](#install), you can run the tests:
@@ -343,24 +401,29 @@ The system consists of two main components.
343
401
  The state machine handles interaction with the robots API and monitors the execution of missions. It also enables
344
402
  interacting with the robot before, during and after missions.
345
403
 
346
- The state machine is based on the [transitions](https://github.com/pytransitions/transitions) package for Python. An visualization of the state machine can be seen below:
347
- ![State Machine](./docs/state_machine_diagram.png)
404
+ The state machine is based on the [transitions](https://github.com/pytransitions/transitions) package for Python. The following are some visualizations of the state machine:
405
+
406
+ Mission behavior without the robot status changed transition that enable the resting states to transition between each other if the robot status changes:
407
+ ![State Machine extended](./docs/extended_state_machine_diagram.png)
408
+
409
+ Robot status changed transition:
410
+ ![State Machine robot status changed](./docs/robot_status_state_machine_diagram.png)
411
+
412
+ Full state machine:
413
+ ![State Machine full](./docs/full_state_machine_diagram.png)
348
414
 
349
415
  In general the states
350
416
 
351
417
  ```
352
- States.Off,
353
- States.Initialize,
354
- States.Initiate,
355
- States.Stop,
418
+ States.Stopping,
356
419
  States.Monitor,
357
420
  States.Paused,
358
421
  ```
359
422
 
360
- indicates that the state machine is already running. For running a mission the state machine need to be in the state
423
+ indicates that the state machine is already running. For running a mission the state machine need to be in the states
361
424
 
362
425
  ```
363
- States.Idle
426
+ States.Home, States.AwaitNextMission or States.ReturningHome
364
427
  ```
365
428
 
366
429
  ### FastAPI
@@ -369,12 +432,6 @@ The FastAPI establishes an interface to the state machine for the user. As the A
369
432
  threads, they communicate through python queues. FastAPI runs on an ASGI-server, specifically uvicorn. The
370
433
  FastAPI-framework is split into routers where the endpoint operations are defined.
371
434
 
372
- ## Mission planner
373
-
374
- The mission planner that is currently in use is a local mission planner, where missions are specified in a json file. You can create your own mission planner by implementing
375
- the [mission planner interface](./src/isar/mission_planner/mission_planner_interface.py) and adding your planner to the
376
- selection [here](./src/isar/modules.py). Note that you must add your module as an option in the dictionary.
377
-
378
435
  ## Storage
379
436
 
380
437
  The storage modules that are used is defined by the `ISAR_STORAGE` configuration variable. This can be changed by
@@ -382,10 +439,10 @@ overriding the configuration through an environment variable. It accepts a json
382
439
  in the list to retrieve the corresponding handler. The current options are
383
440
 
384
441
  ```
385
- ISAR_STORAGE = '["local", "blob", "slimm"]'
442
+ ISAR_STORAGE = '["local", "blob"]'
386
443
  ```
387
444
 
388
- Note that the `blob` and `slimm` options require special configuration to authenticate to these endpoints.
445
+ Note that the `blob` option requires special configuration to authenticate to these endpoints.
389
446
 
390
447
  ### Implement your own storage module
391
448
 
@@ -393,68 +450,6 @@ You can create your own storage module by implementing the [storage interface](.
393
450
  and adding your storage module to the selection [here](./src/isar/modules.py). Note that you must add your module as an
394
451
  option in the dictionary.
395
452
 
396
- ## Task selection
397
-
398
- The tasks of a mission are selected based on a task selector module, defined by the `TASK_SELECTOR` configuration variable. The default task selector is `sequential`. When using the default module, tasks are executed in sequential order defined by the current input mission.
399
-
400
- ### Implement you own task selector module
401
-
402
- Custom task selector modules may be added by implementing additional versions of the [task selector interface](./src/isar/mission_planner/task_selector_interface.py).
403
-
404
- For every custom module, the interface function `next_task()` must be implemented. All interface implementations by default have access to the list of tasks in the current mission through the member `self.tasks`, however additional variables may be supplied by adding arguments to `next_task()`. To comply with the interface definition, the function should return the next task upon every call, and raise the `TaskSelectorStop` exception when all tasks in the current mission have been completed:
405
-
406
- ```python
407
- class CustomTaskSelector(TaskSelectorInterface):
408
- ...
409
- def next_task(...) -> Task:
410
-
411
- # Add code here
412
- ...
413
-
414
- # Raise `TaskSelectorStop` when all tasks have been completed
415
- ...
416
- ```
417
-
418
- Optionally, the `initialize()` function may be extended by supplementing the parameter list or function body:
419
-
420
- ```python
421
- class CustomTaskSelector(TaskSelectorInterface):
422
- ...
423
- def initialize(self, tasks: List[Task], ...) -> None:
424
- super.initialize(tasks=tasks)
425
-
426
- # Add supplementary code here
427
- ...
428
- ```
429
-
430
- A custom task selector may be made available during [module selection](./src/isar/modules.py) by adding it to the series of options in the dictionary of injector modules. It can then be activated by overriding the task selector configuration variable:
431
-
432
- ```python
433
- # Add custom task selector module to `modules.py`
434
-
435
- class CustomTaskSelectorModule(Module):
436
- @provider
437
- @singleton
438
- def provide_task_selector(self) -> TaskSelectorInterface:
439
- return CustomTaskSelector()
440
-
441
- ...
442
-
443
- # Make it available to select during injector instantiation
444
-
445
- modules: dict[str, tuple[Module, Union[str, bool]]] = {
446
- ...
447
- "task_selector": (
448
- {
449
- "sequential": SequentialTaskSelectorModule,
450
- "custom": CustomTaskSelectorModule
451
- }
452
- ...
453
- )
454
- ...
455
- }
456
- ```
457
-
458
453
  ## API authentication
459
454
 
460
455
  The API has an option to include user authentication. This can be enabled by setting the environment variable
@@ -471,6 +466,7 @@ Enabling API authentication also requires the same environment variables. The re
471
466
  AZURE_CLIENT_ID
472
467
  AZURE_TENANT_ID
473
468
  AZURE_CLIENT_SECRET
469
+ ISAR_BLOB_STORAGE_ACCOUNT
474
470
  ```
475
471
 
476
472
  ## MQTT communication
@@ -0,0 +1,120 @@
1
+ isar/__init__.py,sha256=cH8p8bVveu3FUL6kBhldcSlLaoHgD82Kd0-SwSNfGXw,87
2
+ isar/modules.py,sha256=lGeMS_E6r7rqK-jV_ERrYPlb5oQp8r6VqowYOt5jgtE,4285
3
+ isar/script.py,sha256=7qMYHCn4SR8OwUhfgfl_hWQgvKJcL7zD-nvnRKRhEKM,5897
4
+ isar/apis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
+ isar/apis/api.py,sha256=M88pyEcn8RO-8_nAyCOvB-MGN2klap609M5XlzPPms0,15095
6
+ isar/apis/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ isar/apis/models/models.py,sha256=UqIzHiqrvI-ICi6H_xlBFH2HHgYHnMWAKlnqrdqM380,2099
8
+ isar/apis/models/start_mission_definition.py,sha256=fcKvxXegYUd0kxye8bb4rm1LaccvtS4auaetOxhAX7Y,6331
9
+ isar/apis/robot_control/robot_controller.py,sha256=RSVlxbw9D668tHWItVLtyjvAnsJkCs2yUSkU3iqeAcY,1393
10
+ isar/apis/schedule/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ isar/apis/schedule/scheduling_controller.py,sha256=Ptvm0iop0IupYGwcS4Thbi0UeXXJ9N0xWmU1NVpfL_k,9875
12
+ isar/apis/security/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ isar/apis/security/authentication.py,sha256=Se2puhe2TUBmfio2RLma52-VSLRhqvWgu0Cd1bhdwMo,2000
14
+ isar/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ isar/config/log.py,sha256=16qEMVKWrAc5I9xgE0xZQBpuYpy7wMz9NT19JVBZlf4,2218
16
+ isar/config/logging.conf,sha256=skjTp6AsXQGW6L6DeMxGszD-XvWu1BAVWjDipQ4QHvU,854
17
+ isar/config/open_telemetry.py,sha256=Lgu0lbRQA-zz6ZDoBKKk0whQex5w18jl1wjqWzHUGdg,3634
18
+ isar/config/settings.py,sha256=DP36AI_ujmQMFLYnIOXuaYbwp25bFCl-FGBfRoAnDc8,11916
19
+ isar/config/certs/ca-cert.pem,sha256=qoNljfad_qcMxhXJIUMLd7nT-Qwf_d4dYSdoOFEOE8I,2179
20
+ isar/config/keyvault/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
+ isar/config/keyvault/keyvault_service.py,sha256=ZOdkjBaKpNXcNsHONPhKOHtCxq201e2TQy2qz1RoY_o,3104
22
+ isar/config/maps/JSP1_intermediate_deck.json,sha256=fdotzN6MVotyLbqpIjRSrbBYM84vogLkdS585NjBnL8,826
23
+ isar/config/maps/JSP1_weather_deck.json,sha256=_dG3cSBI8q4_uHqHMOO5kSYqMXn85JL3_9PaH4uk1yQ,832
24
+ isar/config/maps/default_map.json,sha256=3CdGMr0Qn3PrL4TfUK8I5a-hotMrS_n5DKfaEORJPT4,776
25
+ isar/config/maps/klab_b.json,sha256=qXgWVUYPaTdVuomf6lQL-uRbV3Tsa6CftnzcbT3dY78,842
26
+ isar/config/maps/klab_compressor.json,sha256=1Vrk5u_l4WXjrTtG4YfXlrCPbOoRs4TtYHOm0430u2A,803
27
+ isar/config/maps/klab_turtlebot.json,sha256=HcB79XFEdY0Wm96EssIFO4TMyAWzc2KENoqN7TbTT0k,823
28
+ isar/config/maps/turtleworld.json,sha256=EKLMpSK9Gu2lAN-E9l41XOaO3f9Su5n_I97mA6z7sWY,764
29
+ isar/eventhandlers/eventhandler.py,sha256=xM5wmrYO3nQtxxsGt-s98ajKhfl3bCMajqtJ29CoGyo,3816
30
+ isar/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
+ isar/models/events.py,sha256=zE2YQoWzfuVTDLX99YdXb4wu6lmc_KZlwWYQAxiNfvA,6262
32
+ isar/models/status.py,sha256=k-z5-a3JjR9ygXw7RMNEDhExd0lwc6Q39I5BW55abP8,646
33
+ isar/robot/robot.py,sha256=uwy7SgF6fx63WaMczch6k54od7LF7_T465DcVp3YZBU,15485
34
+ isar/robot/robot_battery.py,sha256=goLdgmn61QCgE2Ja3YuiwE_sqJzIhCkS3u90sz1kdug,2089
35
+ isar/robot/robot_monitor_mission.py,sha256=Pb0dhnVncNt6VuiidlJDyniEXiqoO1ZArSCdWCqX6IY,13831
36
+ isar/robot/robot_pause_mission.py,sha256=2zVQLh1Qoo-PIgpYUd6IBA39EJ1azIGh_lV1b9BeXqk,2631
37
+ isar/robot/robot_resume_mission.py,sha256=naseBgY3mX1p4lsfW2lW_bocuHO59VHx3fhprxi3Nf0,2417
38
+ isar/robot/robot_start_mission.py,sha256=UFwhSTBbCo-R4FO-BnrCB7bnvOkL1p_0CMDuxnSWi5E,2435
39
+ isar/robot/robot_status.py,sha256=dfAls3s8_Vha7ZMLSYngELqsdpaEpcweAWRHanQj8u8,2361
40
+ isar/robot/robot_stop_mission.py,sha256=CaXLsZjjazHmydU9iR7uOWUHtJ2zvKh4ItUbkWY5sIk,2321
41
+ isar/robot/robot_upload_inspection.py,sha256=uCc9nuH1Am5uxD2Tgnm4ZTOm0tQnud0F6eHs0rSUfvY,2539
42
+ isar/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
+ isar/services/service_connections/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
44
+ isar/services/service_connections/persistent_memory.py,sha256=duNj5vX4VtL5XCu6oiZ0VPmNMlFbNJMzcLcQL8nNfN8,2188
45
+ isar/services/service_connections/mqtt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
+ isar/services/service_connections/mqtt/mqtt_client.py,sha256=8Dr65JNwPx5-kRY8UsRtZ_nrQ2gXXSUH6LWFOYlnluo,4482
47
+ isar/services/service_connections/mqtt/robot_heartbeat_publisher.py,sha256=SKPvY2QwBxqnhL9aGuZQDGQ8F_NDqPtQI5bzRBIUxkQ,1203
48
+ isar/services/service_connections/mqtt/robot_info_publisher.py,sha256=AxokGk51hRPTxxD2r0P9braPJCMrf1InaCxrUBKkF4g,1402
49
+ isar/services/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
+ isar/services/utilities/mqtt_utilities.py,sha256=_e-UzWcoXvsBUrvb89rNXQaDN4G3rTsYlZRIhmC9fQc,3101
51
+ isar/services/utilities/robot_utilities.py,sha256=4zCigsLXfqDC8POHchktSq81zr1_pTaRve_LQsVr6Mk,514
52
+ isar/services/utilities/scheduling_utilities.py,sha256=Q3wrwxbKVptwOTvFShN0meqCmhroJFRKpO56WHq9UzY,22229
53
+ isar/state_machine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
+ isar/state_machine/state_machine.py,sha256=EiYd1g1PzOPBmYXBwBnN0M5T4vRphPUKjgRXmzW8X38,14737
55
+ isar/state_machine/states_enum.py,sha256=JrLLju4KMs2ddJZ0Rou2T1LPzF1SnRzDyr0uA_gUvh0,1127
56
+ isar/state_machine/states/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
+ isar/state_machine/states/await_next_mission.py,sha256=IJ79RuPveK6xBnHHkMldZ8LJybLfhMcS812t7-I6-iU,4381
58
+ isar/state_machine/states/blocked_protective_stop.py,sha256=Ya5GIZS81olGoTXqKVjDaUXfl3zR6FxdsUXktPJIU80,2578
59
+ isar/state_machine/states/going_to_lockdown.py,sha256=dmOhTkg3zNLIIdxfC9b5ss0rWu-pHm-yol2ASoOIUqo,3879
60
+ isar/state_machine/states/going_to_recharging.py,sha256=CMtA9hmiW8XmH7Skj3B0_IAtdZcJCNt_qAvUL0Rmqgg,3562
61
+ isar/state_machine/states/home.py,sha256=IfAFi9bDvoqNaJRahAw8tQwRQ2Wg84kI-nAmtzXp75U,4856
62
+ isar/state_machine/states/intervention_needed.py,sha256=DmRm5bQYxUzTRCwYiFN9L4bRXWSdGgDKCBwh-hV6ySo,3156
63
+ isar/state_machine/states/lockdown.py,sha256=ZFw9XMDENECuH3lh89RKeU_3CTzW0ZBvqCKptFJG5xo,1364
64
+ isar/state_machine/states/maintenance.py,sha256=94lzo7yJbyiphjk_onTETq_ZjMk6PIHRSh4LWEJeC74,1556
65
+ isar/state_machine/states/monitor.py,sha256=WYhCkZAfsGoqO092jvnuSJEspY5gBje__-pf4nuGEDY,6267
66
+ isar/state_machine/states/offline.py,sha256=FbchMo1q2d0aZUiDj9VWuD1IAha7sD1d8e5MqyR_JBc,2564
67
+ isar/state_machine/states/paused.py,sha256=-XRjjMpzKgKQZ7oYmI1bAZXNbtti1KHlH0tt59Cv0eg,4149
68
+ isar/state_machine/states/pausing.py,sha256=Q0yH9iTWA-2yGGsD_atb_bqFJG8cApPfmd_TdcGvRbY,1693
69
+ isar/state_machine/states/pausing_return_home.py,sha256=yEMojzOwn6z2u80S1BF2gVVgs3SOLk90LscO3DIj1R8,1740
70
+ isar/state_machine/states/recharging.py,sha256=9VszfV5zAPOaAcI_k_if6uapu7lO3XDWj6GbvnldnEI,3143
71
+ isar/state_machine/states/resuming.py,sha256=Evh9gxxntKwY8MKM4gn0Sq-H9DpMx6RRJrID57LIv4Y,2071
72
+ isar/state_machine/states/resuming_return_home.py,sha256=YZhHno_WdtR5DkoeKmsN4jALmTXcOdWgOGZ0d8Tz2HQ,2414
73
+ isar/state_machine/states/return_home_paused.py,sha256=598K-hKMxjZZf3iVWDaOOauAETSwJxxDbU1wlHnt9UM,4485
74
+ isar/state_machine/states/returning_home.py,sha256=oXc7Ou7lhzLSm4oZocoiB_4I2vUyxzt2CvJP6wAJhRs,9196
75
+ isar/state_machine/states/stopping.py,sha256=CFdR5vTndXD0T1ZeBO31lSYTxG3ltkNCjjg8biDtpDM,2831
76
+ isar/state_machine/states/stopping_due_to_maintenance.py,sha256=Mjbwf6bQIB0ihBKrsTxnCCUzkIe0LNybVHiLGzcXSNA,2561
77
+ isar/state_machine/states/stopping_go_to_lockdown.py,sha256=_w9yL8Uq2E6W97-ccp9NJvbfjV2hv87LEK_skS5Jhqg,2327
78
+ isar/state_machine/states/stopping_go_to_recharge.py,sha256=02i37QI_551o-i_Ejc3Z9_xuI9o0g8e6WKCXcwkW2ac,1923
79
+ isar/state_machine/states/stopping_paused_mission.py,sha256=IK0qEee_WKnFVs-zLmQc_2xEw3Wge3DKybmFA7zwq8U,1272
80
+ isar/state_machine/states/stopping_paused_return_home.py,sha256=TMVTvBP2ol5rGmuR-fJwmWTUWJWyI5PXnACbclGYvxI,2278
81
+ isar/state_machine/states/stopping_return_home.py,sha256=DA7kluiVA6nWCfX_hEnvuzc8J-TR7V-FGh4wyoyMB8k,2258
82
+ isar/state_machine/states/unknown_status.py,sha256=q5g7ve7R_BdyZYYvVidjIFX2zyPXgKVRdGaJvKiYrH4,3293
83
+ isar/state_machine/transitions/mission.py,sha256=V6ZJaswVCdC7zBlNcD4U4vSb3mjVbZIItl8fcAo7ZKs,8410
84
+ isar/state_machine/transitions/return_home.py,sha256=D_tnpoWNdRTVvwLI2wFeec86l60XU5PTkL2zNe6kghE,3827
85
+ isar/state_machine/transitions/robot_status.py,sha256=EJhzbY-11M_UJA0_1oC95Qy7ByhKR_cOm58ppEBhwqI,2969
86
+ isar/state_machine/utils/common_event_handlers.py,sha256=wL5xdcN0GBlNLqjDJrCpyBiz2YaeBsZRkE51kFIsyw8,4876
87
+ isar/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
88
+ isar/storage/blob_storage.py,sha256=d44z3XpZDUbiKwN8Av2gytTJxnefMXrp5VhiGm4PWxU,3703
89
+ isar/storage/local_storage.py,sha256=Rn-iiiz9DI7PzIhevOMshPIaqzJaqBXeVJMQRhVSl2M,2191
90
+ isar/storage/storage_interface.py,sha256=x-imVeQTdL6dCaTaPTHpXwCR6N4e27WxK_Vpumg0x-Y,1230
91
+ isar/storage/uploader.py,sha256=0BBrxyZGGRkNxGeZeoREucegs4yKUow2523oLEie07o,10841
92
+ isar/storage/utilities.py,sha256=oLH0Rp7UtrQQdilfITnmXO1Z0ExdeDhBImYHid55vBA,3449
93
+ isar-1.34.13.dist-info/licenses/LICENSE,sha256=3fc2-ebLwHWwzfQbulGNRdcNob3SBQeCfEVUDYxsuqw,14058
94
+ robot_interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
95
+ robot_interface/robot_interface.py,sha256=s04zOYDpnUu3GxUyDo3DlX1cFf94DmSt-GrwsFPgnYw,9357
96
+ robot_interface/test_robot_interface.py,sha256=FV1urn7SbsMyWBIcTKjsBwAG4IsXeZ6pLHE0mA9EGGs,692
97
+ robot_interface/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
98
+ robot_interface/models/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
99
+ robot_interface/models/exceptions/robot_exceptions.py,sha256=7extsX9NuJsJ00xeTQ0aI7yeVGW-dzjbH-LH8Mc-uEQ,10821
100
+ robot_interface/models/inspection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
101
+ robot_interface/models/inspection/inspection.py,sha256=cjAvekL8r82s7bgukWeXpYylHvJG_oRSCJNISPVCvZg,2238
102
+ robot_interface/models/mission/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
103
+ robot_interface/models/mission/mission.py,sha256=MQ9p5cuclLXexaZu9bkDh5-aN99eunvYC0vP-Z_kUwI,960
104
+ robot_interface/models/mission/status.py,sha256=3KHA02Jer-HSOwFmUhRkE6cr81H1zPgbwB3p4IjchEY,702
105
+ robot_interface/models/mission/task.py,sha256=SEsdR82CIcqTymecMqYjuY3Nijj_LS90YJdxiConJag,4207
106
+ robot_interface/models/robots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
107
+ robot_interface/models/robots/battery_state.py,sha256=ktOtJ8ltdK0k_i7BoqYfhc5dbOzIG6Oo-uWC67fCWio,98
108
+ robot_interface/models/robots/media.py,sha256=8A-CuuubfngzPprs6zWB9hSaqe3jzgsE8rcCzRX2Uto,227
109
+ robot_interface/models/robots/robot_model.py,sha256=-0jNKWPcEgtF_2klb1It3u0SCoAR0hSW9nce58Zq0Co,417
110
+ robot_interface/telemetry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
111
+ robot_interface/telemetry/mqtt_client.py,sha256=0P1S9mWdJcByGoSOwwn2NPQr9I-OX4b1VPbrIYOU-Zo,4334
112
+ robot_interface/telemetry/payloads.py,sha256=4EaJ45A90j8kCRBGs-2pZvYjYUCkxFNn4NpYJhZCdR4,3246
113
+ robot_interface/utilities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
114
+ robot_interface/utilities/json_service.py,sha256=9N1zijW7K4d3WFR2autpaS8U9o1ibymiOX-6stTKCyk,1243
115
+ robot_interface/utilities/uuid_string_factory.py,sha256=_NQIbBQ56w0qqO0MUDP6aPpHbxW7ATRhK8HnQiBSLkc,76
116
+ isar-1.34.13.dist-info/METADATA,sha256=XFe7UB1O2-NH6RUGUQfrALGCEWWKjK9CjdhV_7bqMF8,29800
117
+ isar-1.34.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
118
+ isar-1.34.13.dist-info/entry_points.txt,sha256=RdnGYFhaBdMGEsOVJAAZxHCflEptjSisHqZ-Rgc4t7Q,98
119
+ isar-1.34.13.dist-info/top_level.txt,sha256=UwIML2RtuQKCyJJkatcSnyp6-ldDjboB9k9JgKipO-U,21
120
+ isar-1.34.13.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.43.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
2
  isar-start = isar.script:start
3
+ isar-test-print = isar.script:print_startup_info