Skip to content

Commit

Permalink
Allow stopping missions from idle state
Browse files Browse the repository at this point in the history
  • Loading branch information
haakonsf committed Nov 20, 2024
1 parent 15afff2 commit 7ddfe35
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 22 deletions.
10 changes: 2 additions & 8 deletions src/isar/apis/schedule/scheduling_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,7 @@
from isar.services.utilities.scheduling_utilities import SchedulingUtilities
from isar.state_machine.states_enum import States
from robot_interface.models.mission.mission import Mission
from robot_interface.models.mission.task import (
TASKS,
Localize,
MoveArm,
ReturnToHome,
)
from robot_interface.models.mission.task import Task
from robot_interface.models.mission.task import TASKS, Localize, MoveArm, ReturnToHome


class SchedulingController:
Expand Down Expand Up @@ -192,7 +186,7 @@ def stop_mission(self) -> ControlMissionResponse:

state: States = self.scheduling_utilities.get_state()

if state in [States.Off, States.Idle]:
if state == States.Off:
error_message = (
f"Conflict - Stop command received in invalid state - State: {state}"
)
Expand Down
27 changes: 21 additions & 6 deletions src/isar/state_machine/state_machine.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,7 @@
from robot_interface.models.exceptions.robot_exceptions import ErrorMessage
from robot_interface.models.initialize.initialize_params import InitializeParams
from robot_interface.models.mission.mission import Mission
from robot_interface.models.mission.status import (
MissionStatus,
RobotStatus,
TaskStatus,
)
from robot_interface.models.mission.status import MissionStatus, RobotStatus, TaskStatus
from robot_interface.models.mission.task import TASKS, Task
from robot_interface.robot_interface import RobotInterface
from robot_interface.telemetry.mqtt_client import MqttClientInterface
Expand Down Expand Up @@ -134,7 +130,11 @@ def __init__(
},
{
"trigger": "stop",
"source": [self.initiate_state, self.monitor_state],
"source": [
self.initiate_state,
self.monitor_state,
self.idle_state,
],
"dest": self.stop_state,
"before": self._stop,
},
Expand Down Expand Up @@ -371,6 +371,11 @@ def _initiate_infeasible(self) -> None:
self.iterate_current_task()

def _mission_stopped(self) -> None:
if self.current_mission is None:
self._queue_empty_response()
self.reset_state_machine()
return

self.current_mission.status = MissionStatus.Cancelled

for task in self.current_mission.tasks:
Expand Down Expand Up @@ -588,6 +593,16 @@ def _make_control_mission_response(self) -> ControlMissionResponse:
task_status=self.current_task.status,
)

def _queue_empty_response(self):
self.queues.stop_mission.output.put(
ControlMissionResponse(
mission_id="None",
mission_status="None",
task_id="None",
task_status="None",
)
)


def main(state_machine: StateMachine):
"""Starts a state machine instance."""
Expand Down
3 changes: 3 additions & 0 deletions src/isar/state_machine/states/idle.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ def stop(self) -> None:

def _run(self) -> None:
while True:
if self.state_machine.should_stop_mission():
transition = self.state_machine.stop # type: ignore
break
start_mission: Optional[StartMissionMessage] = (
self.state_machine.should_start_mission()
)
Expand Down
9 changes: 1 addition & 8 deletions tests/isar/apis/scheduler/test_scheduler_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ class TestStopMission:
valid_states = [
States.Initiate,
States.Initialize,
States.Idle,
States.Monitor,
States.Paused,
States.Stop,
Expand All @@ -286,14 +287,6 @@ def test_stop_mission(
assert response.status_code == HTTPStatus.OK
assert response.json() == jsonable_encoder(mock_control_mission_response)

@mock.patch.object(SchedulingUtilities, "get_state", mock_return_idle)
@mock.patch.object(
SchedulingUtilities, "stop_mission", mock_control_mission_response
)
def test_can_not_stop_mission_in_idle(self, client: TestClient):
response = client.post(url=self.schedule_stop_mission_path)
assert response.status_code == HTTPStatus.CONFLICT

@mock.patch.object(SchedulingUtilities, "get_state", mock_return_off)
@mock.patch.object(
SchedulingUtilities, "stop_mission", mock_control_mission_response
Expand Down

0 comments on commit 7ddfe35

Please sign in to comment.