Skip to content

Commit

Permalink
Improve estimate for remainding time
Browse files Browse the repository at this point in the history
  • Loading branch information
Eddasol committed Jan 30, 2025
1 parent 58e4b19 commit 7735691
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 64 deletions.
10 changes: 5 additions & 5 deletions backend/api/Controllers/MissionSchedulingController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ [FromBody] ScheduleMissionQuery scheduledMissionQuery

if (newMissionRun.Tasks.Any())
{
newMissionRun.CalculateEstimatedDuration();
newMissionRun.SetEstimatedTaskDuration();
}

// Compare with GetTasksFromSource
Expand Down Expand Up @@ -221,7 +221,7 @@ await localizationService.EnsureRobotIsOnSameInstallationAsMission(

if (missionRun.Tasks.Any())
{
missionRun.CalculateEstimatedDuration();
missionRun.SetEstimatedTaskDuration();
}

MissionRun newMissionRun;
Expand Down Expand Up @@ -428,7 +428,7 @@ [.. missionInspectionAreaNames]

if (missionRun.Tasks.Any())
{
missionRun.CalculateEstimatedDuration();
missionRun.SetEstimatedTaskDuration();
}

if (existingMissionDefinition == null)
Expand Down Expand Up @@ -623,7 +623,7 @@ await localizationService.EnsureRobotIsOnSameInstallationAsMission(

if (scheduledMission.Tasks.Any())
{
scheduledMission.CalculateEstimatedDuration();
scheduledMission.SetEstimatedTaskDuration();
}
else if (
scheduledMission.Robot.CurrentInspectionArea != null
Expand All @@ -633,7 +633,7 @@ await localizationService.EnsureRobotIsOnSameInstallationAsMission(
)
)
{
scheduledMission.CalculateEstimatedDuration();
scheduledMission.SetEstimatedTaskDuration();
}

if (
Expand Down
4 changes: 2 additions & 2 deletions backend/api/Controllers/Models/MissionRunResponse.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class MissionRunResponse

public DateTime? EndTime { get; private set; }

public uint? EstimatedDuration { get; set; }
public uint? EstimatedTaskDuration { get; set; }

public IList<MissionTask> Tasks { get; set; }

Expand Down Expand Up @@ -67,7 +67,7 @@ public MissionRunResponse(MissionRun mission)
DesiredStartTime = mission.DesiredStartTime;
StartTime = mission.StartTime;
EndTime = mission.EndTime;
EstimatedDuration = mission.EstimatedDuration;
EstimatedTaskDuration = mission.EstimatedTaskDuration;
Tasks = mission.Tasks;
MissionRunType = mission.MissionRunType;
}
Expand Down
39 changes: 4 additions & 35 deletions backend/api/Database/Models/MissionRun.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ or MissionStatus.PartiallySuccessful
public DateTime? EndTime { get; private set; }

/// <summary>
/// The estimated duration of the mission in seconds
/// The estimated duration of each task in the mission in seconds
/// </summary>
public uint? EstimatedDuration { get; set; }
public uint? EstimatedTaskDuration { get; set; }

[Required]
[MaxLength(200)]
Expand Down Expand Up @@ -129,42 +129,11 @@ public static MissionStatus GetMissionStatusFromString(string status)
};
}

public void CalculateEstimatedDuration()
public void SetEstimatedTaskDuration()
{
if (Robot.Model.AverageDurationPerTag is not null)
{
float totalInspectionDuration = Tasks.Sum(task =>
task.Inspection?.VideoDuration ?? 0
);
EstimatedDuration = (uint)(
(Robot.Model.AverageDurationPerTag * Tasks.Count) + totalInspectionDuration
);
}
else
{
const double RobotVelocity = 1.5 * 1000 / 60; // km/t => m/min
const double EfficiencyFactor = 0.20;
const double InspectionTime = 2; // min/tag
const int AssumedXyMetersFromFirst = 20;

double distance = 0;
var prevPosition = new Position(
Tasks.First().RobotPose.Position.X + AssumedXyMetersFromFirst,
Tasks.First().RobotPose.Position.Y + AssumedXyMetersFromFirst,
Tasks.First().RobotPose.Position.Z
);
foreach (var task in Tasks)
{
var currentPosition = task.RobotPose.Position;
distance +=
Math.Abs(currentPosition.X - prevPosition.X)
+ Math.Abs(currentPosition.Y - prevPosition.Y);
prevPosition = currentPosition;
}
int estimate = (int)(
(distance / (RobotVelocity * EfficiencyFactor)) + InspectionTime
);
EstimatedDuration = (uint)estimate * 60;
EstimatedTaskDuration = (uint)Robot.Model.AverageDurationPerTag;
}
}

Expand Down
4 changes: 0 additions & 4 deletions backend/api/Services/Models/IsarMissionDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,6 @@ public IsarInspectionDefinition(
{
{ "map", mapName },
{ "description", missionRun.Description },
{
"estimated_duration",
missionRun.EstimatedDuration?.ToString("D", CultureInfo.InvariantCulture)
},
{ "asset_code", missionRun.InstallationCode },
{ "mission_name", missionRun.Name },
{ "status_reason", missionRun.StatusReason },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useLanguageContext } from 'components/Contexts/LanguageContext'
import { Icons } from 'utils/icons'
import { StyledDialog } from 'components/Styles/StyledComponents'
import { tokens } from '@equinor/eds-tokens'
import { calculateRemaindingTimeInMinutes } from 'components/Pages/MissionPage/MissionHeader/MissionHeader'

interface MissionQueueCardProps {
order: number
Expand Down Expand Up @@ -159,23 +160,24 @@ const RemoveMissionDialog = ({
const MissionDetails = ({ mission }: { mission: Mission }) => {
const { TranslateText } = useLanguageContext()

const estimatedDuration = () => {
const getEstimatedDuration = () => {
const translateEstimatedDuration = TranslateText('Estimated duration')
const translateH = TranslateText('h')
const translateMin = TranslateText('min')
const translateNotAvailable = TranslateText('Estimated duration: not available')
if (mission.estimatedDuration !== undefined) {
const hours = Math.floor(mission.estimatedDuration / 3600)
const remainingSeconds = mission.estimatedDuration % 3600
const minutes = Math.ceil(remainingSeconds / 60)

return `${translateEstimatedDuration}: ${hours} ${translateH} ${minutes} ${translateMin}`
if (mission.estimatedTaskDuration) {
const estimatedDuration = calculateRemaindingTimeInMinutes(mission.tasks, mission.estimatedTaskDuration)
const hours = Math.floor(estimatedDuration / 60)
const remainingMinutes = Math.ceil(estimatedDuration % 60)

return `${translateEstimatedDuration}: ${hours} ${translateH} ${remainingMinutes} ${translateMin}`
}
return translateNotAvailable
}

const tasks = `${TranslateText('Tasks')}: ${mission.tasks.length}`
const missionDetails = `${tasks} | ${estimatedDuration()}`
const missionDetails = `${tasks} | ${getEstimatedDuration()}`

return (
<Typography variant="caption" color={tokens.colors.text.static_icons__tertiary.hex}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Card, Typography } from '@equinor/eds-core-react'
import { MissionControlButtons } from 'components/Displays/MissionButtons/MissionControlButtons'
import { MissionStatusDisplay } from 'components/Displays/MissionDisplays/MissionStatusDisplay'
import { differenceInMinutes } from 'date-fns'
import { differenceInMinutes, differenceInSeconds } from 'date-fns'
import { Mission, MissionStatus } from 'models/Mission'
import { tokens } from '@equinor/eds-tokens'
import styled from 'styled-components'
import { useLanguageContext } from 'components/Contexts/LanguageContext'
import { StatusReason } from '../StatusReason'
import { MissionRestartButton } from 'components/Displays/MissionButtons/MissionRestartButton'
import { TaskStatus, TaskType } from 'models/Task'
import { Task, TaskStatus, TaskType } from 'models/Task'
import { convertUTCDateToLocalDate, formatDateTime } from 'utils/StringFormatting'

const HeaderSection = styled(Card)`
Expand Down Expand Up @@ -83,6 +83,21 @@ const HeaderText = (title: string, text: string) => {
)
}

export const calculateRemaindingTimeInMinutes = (tasks: Task[], estimatedTaskDuration: number) => {
const estimatedTaskDurations = tasks.map((task) => {
if (task.status === TaskStatus.NotStarted || task.status === TaskStatus.Paused) {
return estimatedTaskDuration + (task.inspection.videoDuration ?? 0)
}
else if (task.status === TaskStatus.InProgress) {
const timeUsed = task.startTime ? differenceInSeconds(Date.now(), convertUTCDateToLocalDate(task.startTime)) : 0
return Math.max(estimatedTaskDuration + (task.inspection.videoDuration ?? 0) - timeUsed, 0)
}
return 0
})
const remandingTimeInSeconds = estimatedTaskDurations.reduce((sum, x) => sum + x)
return Math.ceil(remandingTimeInSeconds / 60)
}

const getStartUsedAndRemainingTime = (
mission: Mission,
translatedMinutes: string
Expand All @@ -96,11 +111,6 @@ const getStartUsedAndRemainingTime = (
let startDate: string
let remainingTime: string
let usedTimeInMinutes: number
let estimatedDurationInMinutes: number | undefined
if (mission.estimatedDuration) {
// Convert from seconds to minutes, rounding up
estimatedDurationInMinutes = Math.ceil(mission.estimatedDuration / 60)
}

if (mission.endTime) {
startTime = mission.startTime
Expand All @@ -121,14 +131,14 @@ const getStartUsedAndRemainingTime = (
startTime = formatDateTime(mission.startTime, 'HH:mm')
startDate = formatDateTime(mission.startTime, 'dd/MM/yyy')
usedTimeInMinutes = differenceInMinutes(Date.now(), convertUTCDateToLocalDate(mission.startTime))
if (estimatedDurationInMinutes)
remainingTime = Math.max(estimatedDurationInMinutes - usedTimeInMinutes, 0) + ' ' + translatedMinutes
if (mission.estimatedTaskDuration)
remainingTime = calculateRemaindingTimeInMinutes(mission.tasks, mission.estimatedTaskDuration) + ' ' + translatedMinutes
else remainingTime = 'N/A'
} else {
startTime = 'N/A'
startDate = 'N/A'
usedTimeInMinutes = 0
if (estimatedDurationInMinutes) remainingTime = estimatedDurationInMinutes + ' ' + translatedMinutes
if (mission.estimatedTaskDuration) remainingTime = calculateRemaindingTimeInMinutes(mission.tasks, mission.estimatedTaskDuration) + ' ' + translatedMinutes
else remainingTime = 'N/A'
}
const usedTime: string = usedTimeInMinutes + ' ' + translatedMinutes
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/models/Mission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export interface Mission {
desiredStartTime: Date
startTime?: Date
endTime?: Date
estimatedDuration?: number
estimatedTaskDuration?: number
tasks: Task[]
}

Expand Down

0 comments on commit 7735691

Please sign in to comment.