diff --git a/backend/api/Controllers/ReturnToHomeController.cs b/backend/api/Controllers/ReturnToHomeController.cs index 5cfdce1d..38e54ab9 100644 --- a/backend/api/Controllers/ReturnToHomeController.cs +++ b/backend/api/Controllers/ReturnToHomeController.cs @@ -31,17 +31,18 @@ [FromRoute] string robotId var robot = await robotService.ReadById(robotId, readOnly: true); if (robot is null) { - logger.LogWarning("Could not find robot with id={Id}", robotId); + logger.LogWarning("Could not find robot with id {Id}", robotId); return NotFound(); } var returnToHomeMission = await returnToHomeService.ScheduleReturnToHomeMissionRunIfNotAlreadyScheduled( - robot + robot, + true ); if (returnToHomeMission is null) { - string errorMessage = "Error while scheduling Return home mission"; + string errorMessage = "Error while scheduling Return Home mission"; logger.LogError(errorMessage); return StatusCode(StatusCodes.Status502BadGateway, $"{errorMessage}"); } diff --git a/backend/api/Services/MissionRunService.cs b/backend/api/Services/MissionRunService.cs index ffd69912..0f610570 100644 --- a/backend/api/Services/MissionRunService.cs +++ b/backend/api/Services/MissionRunService.cs @@ -267,21 +267,18 @@ public async Task> ReadMissionRuns( public async Task PendingOrOngoingReturnToHomeMissionRunExists(string robotId) { - var pendingMissionRuns = await ReadNextScheduledMissionRun( - robotId, - type: MissionRunType.ReturnHome, - readOnly: true - ); - if (pendingMissionRuns != null) - return true; - - var ongoingMissionRuns = await GetMissionRunsWithSubModels(readOnly: true) + var pendingAndOngoingMissionRuns = await GetMissionRunsWithSubModels(readOnly: true) .Where(missionRun => - missionRun.Robot.Id == robotId && missionRun.Status == MissionStatus.Ongoing + missionRun.Robot.Id == robotId + && ( + missionRun.Status == MissionStatus.Ongoing + || missionRun.Status == MissionStatus.Paused + || missionRun.Status == MissionStatus.Pending + ) ) .OrderBy(missionRun => missionRun.DesiredStartTime) .ToListAsync(); - return ongoingMissionRuns.Any((m) => m.IsReturnHomeMission()); + return pendingAndOngoingMissionRuns.Any((m) => m.IsReturnHomeMission()); } public bool IncludesUnsupportedInspectionType(MissionRun missionRun) diff --git a/backend/api/Services/MissionSchedulingService.cs b/backend/api/Services/MissionSchedulingService.cs index 730fd51b..9db9ea25 100644 --- a/backend/api/Services/MissionSchedulingService.cs +++ b/backend/api/Services/MissionSchedulingService.cs @@ -70,7 +70,7 @@ public async Task StartNextMissionRunIfSystemIsAvailable(Robot robot) ) { logger.LogInformation( - "Robot {robotName} was ready to start a mission but its mission queue was frozen", + "Robot {robotName} is ready to start a mission but its mission queue is frozen", robot.Name ); return; @@ -88,19 +88,19 @@ public async Task StartNextMissionRunIfSystemIsAvailable(Robot robot) if (missionRun.InspectionArea == null) { logger.LogWarning( - "Mission {MissionRunId} does not have an inspection area and was therefore not started", + "Mission {MissionRunId} cannot be started as it does not have an inspection area", missionRun.Id ); return; } - if (robot.CurrentInspectionArea == null && missionRun.InspectionArea != null) + if (robot.CurrentInspectionArea == null) { await robotService.UpdateCurrentInspectionArea( robot.Id, - missionRun.InspectionArea.Id + missionRun.InspectionArea!.Id ); - robot.CurrentInspectionArea = missionRun.InspectionArea; + robot.CurrentInspectionArea = missionRun.InspectionArea!; } else if ( !await localizationService.RobotIsOnSameInspectionAreaAsMission( @@ -110,7 +110,8 @@ await robotService.UpdateCurrentInspectionArea( ) { logger.LogError( - "Robot {RobotId} is not on the same inspection area as the mission run {MissionRunId}. Aborting all mission runs", + "Robot {RobotNAme} with Id {RobotId} is not on the same inspection area as the mission run with Id {MissionRunId}. Aborting all mission runs", + robot.Name, robot.Id, missionRun.Id ); @@ -118,13 +119,15 @@ await robotService.UpdateCurrentInspectionArea( { await AbortAllScheduledNormalMissions( robot.Id, - "Aborted: Robot was at different inspection area" + $"All missions aborted: Robot {robot.Name} is on inspection area {robot.CurrentInspectionArea?.Name} " + + $"and mission run was on inspection area {missionRun.InspectionArea?.Name}" ); } catch (RobotNotFoundException) { logger.LogError( - "Failed to abort scheduled missions for robot {RobotId}", + "Failed to abort all scheduled missions for robot {RobotName} with Id {RobotId}", + robot.Name, robot.Id ); } @@ -232,12 +235,16 @@ public async Task HandleBatteryAndPressureLevel(Robot robot) { await AbortAllScheduledNormalMissions( robot.Id, - "Aborted: Robot pressure or battery values are too low." + $"Mission aborted for robot {robot.Name}: pressure or battery values too low." ); } catch (RobotNotFoundException) { - logger.LogError("Failed to abort scheduled missions for robot {RobotId}", robot.Id); + logger.LogError( + "Failed to abort scheduled missions for robot {RobotName} with Id {RobotId} since the robot was not found", + robot.Name, + robot.Id + ); } } diff --git a/backend/api/Services/ReturnToHomeService.cs b/backend/api/Services/ReturnToHomeService.cs index 5ed02ad2..da6e1cf1 100644 --- a/backend/api/Services/ReturnToHomeService.cs +++ b/backend/api/Services/ReturnToHomeService.cs @@ -5,7 +5,10 @@ namespace Api.Services { public interface IReturnToHomeService { - public Task ScheduleReturnToHomeMissionRunIfNotAlreadyScheduled(Robot robot); + public Task ScheduleReturnToHomeMissionRunIfNotAlreadyScheduled( + Robot robot, + bool shouldTriggerMissionCreatedEvent = false + ); public Task GetActiveReturnToHomeMissionRun( string robotId, bool readOnly = true @@ -18,18 +21,21 @@ IMissionRunService missionRunService ) : IReturnToHomeService { public async Task ScheduleReturnToHomeMissionRunIfNotAlreadyScheduled( - Robot robot + Robot robot, + bool shouldTriggerMissionCreatedEvent = false ) { logger.LogInformation( - "Scheduling return home mission if not already scheduled or the robot is home for robot {RobotId}", + "Scheduling return home mission if not already scheduled and the robot is not home for Robot {RobotName} with Id {RobotId}", + robot.Name, robot.Id ); if (await IsReturnToHomeMissionAlreadyScheduled(robot.Id)) { logger.LogInformation( - "ReturnToHomeMission is already scheduled for Robot {RobotId}", + "Return Home Mission already scheduled for Robot {RobotName} with Id {RobotId}", + robot.Name, robot.Id ); return null; @@ -38,7 +44,10 @@ Robot robot MissionRun missionRun; try { - missionRun = await ScheduleReturnToHomeMissionRun(robot); + missionRun = await ScheduleReturnToHomeMissionRun( + robot, + shouldTriggerMissionCreatedEvent + ); } catch (Exception ex) when (ex @@ -61,9 +70,12 @@ private async Task IsReturnToHomeMissionAlreadyScheduled(string robotId) return await missionRunService.PendingOrOngoingReturnToHomeMissionRunExists(robotId); } - private async Task ScheduleReturnToHomeMissionRun(Robot robot) + private async Task ScheduleReturnToHomeMissionRun( + Robot robot, + bool shouldTriggerMissionCreatedEvent = false + ) { - Pose? return_to_home_pose; + Pose? returnToHomePose; InspectionArea? currentInspectionArea; if ( robot.RobotCapabilities is not null @@ -75,7 +87,7 @@ robot.RobotCapabilities is not null readOnly: true ); currentInspectionArea = previousMissionRun?.InspectionArea; - return_to_home_pose = + returnToHomePose = previousMissionRun?.InspectionArea?.DefaultLocalizationPose?.Pose == null ? new Pose() : new Pose(previousMissionRun.InspectionArea.DefaultLocalizationPose.Pose); @@ -83,7 +95,7 @@ robot.RobotCapabilities is not null else { currentInspectionArea = robot.CurrentInspectionArea; - return_to_home_pose = + returnToHomePose = robot.CurrentInspectionArea?.DefaultLocalizationPose?.Pose == null ? new Pose() : new Pose(robot.CurrentInspectionArea.DefaultLocalizationPose.Pose); @@ -92,26 +104,29 @@ robot.RobotCapabilities is not null if (currentInspectionArea == null) { string errorMessage = - $"Robot with ID {robot.Id} could return home as it did not have an inspection area"; - logger.LogError("{Message}", errorMessage); + $"Robot with ID {robot.Id} could not return to home because it does not have an inspection area"; + logger.LogError("Message: {Message}", errorMessage); throw new InspectionAreaNotFoundException(errorMessage); } var returnToHomeMissionRun = new MissionRun { - Name = "Return home", + Name = "Return Home", Robot = robot, InstallationCode = robot.CurrentInstallation.InstallationCode, MissionRunType = MissionRunType.ReturnHome, InspectionArea = currentInspectionArea!, Status = MissionStatus.Pending, DesiredStartTime = DateTime.UtcNow, - Tasks = [new(return_to_home_pose, MissionTaskType.ReturnHome)], + Tasks = [new(returnToHomePose, MissionTaskType.ReturnHome)], }; - var missionRun = await missionRunService.Create(returnToHomeMissionRun, false); + var missionRun = await missionRunService.Create( + returnToHomeMissionRun, + shouldTriggerMissionCreatedEvent + ); logger.LogInformation( - "Scheduled a mission for the robot {RobotName} to return to home location on inspection area {InspectionAreaName}", + "Scheduled Return to Home mission for robot {RobotName} on Inspection Area {InspectionAreaName}", robot.Name, currentInspectionArea?.Name );