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

Inspect return to home #1988

Merged
merged 1 commit into from
Jan 28, 2025
Merged
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
7 changes: 4 additions & 3 deletions backend/api/Controllers/ReturnToHomeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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}");
}
Expand Down
19 changes: 8 additions & 11 deletions backend/api/Services/MissionRunService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -267,21 +267,18 @@ public async Task<IList<MissionRun>> ReadMissionRuns(

public async Task<bool> 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)
Expand Down
27 changes: 17 additions & 10 deletions backend/api/Services/MissionSchedulingService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we ensure that this is not null?

);
robot.CurrentInspectionArea = missionRun.InspectionArea;
robot.CurrentInspectionArea = missionRun.InspectionArea!;
}
else if (
!await localizationService.RobotIsOnSameInspectionAreaAsMission(
Expand All @@ -110,21 +110,24 @@ 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
);
try
{
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
);
}
Expand Down Expand Up @@ -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
);
}
}

Expand Down
45 changes: 30 additions & 15 deletions backend/api/Services/ReturnToHomeService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ namespace Api.Services
{
public interface IReturnToHomeService
{
public Task<MissionRun?> ScheduleReturnToHomeMissionRunIfNotAlreadyScheduled(Robot robot);
public Task<MissionRun?> ScheduleReturnToHomeMissionRunIfNotAlreadyScheduled(
Robot robot,
bool shouldTriggerMissionCreatedEvent = false
oysand marked this conversation as resolved.
Show resolved Hide resolved
);
public Task<MissionRun?> GetActiveReturnToHomeMissionRun(
string robotId,
bool readOnly = true
Expand All @@ -18,18 +21,21 @@ IMissionRunService missionRunService
) : IReturnToHomeService
{
public async Task<MissionRun?> 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;
Expand All @@ -38,7 +44,10 @@ Robot robot
MissionRun missionRun;
try
{
missionRun = await ScheduleReturnToHomeMissionRun(robot);
missionRun = await ScheduleReturnToHomeMissionRun(
robot,
shouldTriggerMissionCreatedEvent
);
}
catch (Exception ex)
when (ex
Expand All @@ -61,9 +70,12 @@ private async Task<bool> IsReturnToHomeMissionAlreadyScheduled(string robotId)
return await missionRunService.PendingOrOngoingReturnToHomeMissionRunExists(robotId);
}

private async Task<MissionRun> ScheduleReturnToHomeMissionRun(Robot robot)
private async Task<MissionRun> ScheduleReturnToHomeMissionRun(
Robot robot,
bool shouldTriggerMissionCreatedEvent = false
)
{
Pose? return_to_home_pose;
Pose? returnToHomePose;
InspectionArea? currentInspectionArea;
if (
robot.RobotCapabilities is not null
Expand All @@ -75,15 +87,15 @@ 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);
}
else
{
currentInspectionArea = robot.CurrentInspectionArea;
return_to_home_pose =
returnToHomePose =
robot.CurrentInspectionArea?.DefaultLocalizationPose?.Pose == null
? new Pose()
: new Pose(robot.CurrentInspectionArea.DefaultLocalizationPose.Pose);
Expand All @@ -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}",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"Scheduled Return to Home mission for robot {RobotName} on Inspection Area {InspectionAreaName}",
"Scheduled Return Home mission for robot {RobotName} on Inspection Area {InspectionAreaName}",

robot.Name,
currentInspectionArea?.Name
);
Expand Down
Loading