Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow stopping missions from idle state #634

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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