From c43a97d9cea3f5c41a515f5845e6a52466099c6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Chirico=20Indreb=C3=B8?= Date: Mon, 16 Dec 2024 14:46:41 +0100 Subject: [PATCH] Make inspectionArea optional and add migrations --- .../MissionSchedulingController.cs | 7 +- .../api/Database/Context/FlotillaDbContext.cs | 2 + .../api/Database/Models/MissionDefinition.cs | 3 +- backend/api/Database/Models/MissionRun.cs | 3 +- ...eaInsteadOfAreaForLocalisation.Designer.cs | 1333 +++++++++++++++++ ...pectionAreaInsteadOfAreaForLocalisation.cs | 408 +++++ .../FlotillaDbContextModelSnapshot.cs | 102 +- .../api/Services/MissionDefinitionService.cs | 6 +- .../api/Services/MissionSchedulingService.cs | 4 +- .../Services/Models/IsarMissionDefinition.cs | 9 +- 10 files changed, 1811 insertions(+), 66 deletions(-) create mode 100644 backend/api/Migrations/20241216130006_UseInspectionAreaInsteadOfAreaForLocalisation.Designer.cs create mode 100644 backend/api/Migrations/20241216130006_UseInspectionAreaInsteadOfAreaForLocalisation.cs diff --git a/backend/api/Controllers/MissionSchedulingController.cs b/backend/api/Controllers/MissionSchedulingController.cs index ce420776b..1406720dc 100644 --- a/backend/api/Controllers/MissionSchedulingController.cs +++ b/backend/api/Controllers/MissionSchedulingController.cs @@ -280,6 +280,11 @@ [FromBody] ScheduledMissionQuery scheduledMissionQuery if (missionDefinitions.Count > 0) { existingMissionDefinition = missionDefinitions.First(); + if (existingMissionDefinition.InspectionArea == null) + { + existingMissionDefinition.InspectionArea = area.Deck; + await missionDefinitionService.Update(existingMissionDefinition); + } } } @@ -319,7 +324,7 @@ [FromBody] ScheduledMissionQuery scheduledMissionQuery await missionDefinitionService.Create(scheduledMissionDefinition); } - if (missionRun.Robot.CurrentInspectionArea != null && !await localizationService.RobotIsOnSameDeckAsMission(missionRun.Robot.Id, missionRun.InspectionArea.Id)) + if (missionRun.Robot.CurrentInspectionArea != null && !await localizationService.RobotIsOnSameDeckAsMission(missionRun.Robot.Id, missionRun.InspectionArea!.Id)) { return Conflict($"The robot {missionRun.Robot.Name} is assumed to be in a different inspection area so the mission was not scheduled."); } diff --git a/backend/api/Database/Context/FlotillaDbContext.cs b/backend/api/Database/Context/FlotillaDbContext.cs index 72f91e40e..9aef1595f 100644 --- a/backend/api/Database/Context/FlotillaDbContext.cs +++ b/backend/api/Database/Context/FlotillaDbContext.cs @@ -66,6 +66,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity().OwnsOne(m => m.Map).OwnsOne(t => t.TransformationMatrices); modelBuilder.Entity().OwnsOne(m => m.Map).OwnsOne(b => b.Boundary); + modelBuilder.Entity().HasOne(m => m.InspectionArea).WithMany().OnDelete(DeleteBehavior.Restrict); + modelBuilder.Entity().HasOne(m => m.InspectionArea).WithMany().OnDelete(DeleteBehavior.Restrict); modelBuilder.Entity().OwnsOne(r => r.Pose).OwnsOne(p => p.Orientation); modelBuilder.Entity().OwnsOne(r => r.Pose).OwnsOne(p => p.Position); diff --git a/backend/api/Database/Models/MissionDefinition.cs b/backend/api/Database/Models/MissionDefinition.cs index 950f41b2b..42cef67ed 100644 --- a/backend/api/Database/Models/MissionDefinition.cs +++ b/backend/api/Database/Models/MissionDefinition.cs @@ -28,8 +28,7 @@ public class MissionDefinition : SortableRecord public virtual MissionRun? LastSuccessfulRun { get; set; } - [Required] - public Deck InspectionArea { get; set; } + public Deck? InspectionArea { get; set; } public MapMetadata? Map { get; set; } diff --git a/backend/api/Database/Models/MissionRun.cs b/backend/api/Database/Models/MissionRun.cs index 650e46498..c2596830c 100644 --- a/backend/api/Database/Models/MissionRun.cs +++ b/backend/api/Database/Models/MissionRun.cs @@ -69,8 +69,7 @@ public IList Tasks [MaxLength(1000)] public string? Comment { get; set; } - [Required] - public Deck InspectionArea { get; set; } + public Deck? InspectionArea { get; set; } public bool IsCompleted => _status diff --git a/backend/api/Migrations/20241216130006_UseInspectionAreaInsteadOfAreaForLocalisation.Designer.cs b/backend/api/Migrations/20241216130006_UseInspectionAreaInsteadOfAreaForLocalisation.Designer.cs new file mode 100644 index 000000000..1de4fe8ce --- /dev/null +++ b/backend/api/Migrations/20241216130006_UseInspectionAreaInsteadOfAreaForLocalisation.Designer.cs @@ -0,0 +1,1333 @@ +// +using System; +using Api.Database.Context; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Api.Migrations +{ + [DbContext(typeof(FlotillaDbContext))] + [Migration("20241216130006_UseInspectionAreaInsteadOfAreaForLocalisation")] + partial class UseInspectionAreaInsteadOfAreaForLocalisation + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.11") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Api.Database.Models.AccessRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("AccessLevel") + .IsRequired() + .HasColumnType("text"); + + b.Property("InstallationId") + .HasColumnType("text"); + + b.Property("RoleName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("InstallationId"); + + b.ToTable("AccessRoles"); + }); + + modelBuilder.Entity("Api.Database.Models.Area", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("DeckId") + .IsRequired() + .HasColumnType("text"); + + b.Property("DefaultLocalizationPoseId") + .HasColumnType("text"); + + b.Property("InstallationId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("PlantId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("DeckId"); + + b.HasIndex("DefaultLocalizationPoseId"); + + b.HasIndex("InstallationId"); + + b.HasIndex("PlantId"); + + b.ToTable("Areas"); + }); + + modelBuilder.Entity("Api.Database.Models.Deck", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("DefaultLocalizationPoseId") + .HasColumnType("text"); + + b.Property("InstallationId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("PlantId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("DefaultLocalizationPoseId"); + + b.HasIndex("InstallationId"); + + b.HasIndex("PlantId"); + + b.ToTable("Decks"); + }); + + modelBuilder.Entity("Api.Database.Models.DefaultLocalizationPose", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("DockingEnabled") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.ToTable("DefaultLocalizationPoses"); + }); + + modelBuilder.Entity("Api.Database.Models.Inspection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("AnalysisType") + .HasColumnType("text"); + + b.Property("EndTime") + .HasColumnType("timestamp with time zone"); + + b.Property("InspectionTargetName") + .HasColumnType("text"); + + b.Property("InspectionType") + .IsRequired() + .HasColumnType("text"); + + b.Property("InspectionUrl") + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("IsarInspectionId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("IsarTaskId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("StartTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("VideoDuration") + .HasColumnType("real"); + + b.HasKey("Id"); + + b.ToTable("Inspections"); + }); + + modelBuilder.Entity("Api.Database.Models.InspectionFinding", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("Finding") + .IsRequired() + .HasColumnType("text"); + + b.Property("InspectionDate") + .HasColumnType("timestamp with time zone"); + + b.Property("InspectionId") + .HasColumnType("text"); + + b.Property("IsarTaskId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("InspectionId"); + + b.ToTable("InspectionFindings"); + }); + + modelBuilder.Entity("Api.Database.Models.Installation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("InstallationCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.HasKey("Id"); + + b.HasIndex("InstallationCode") + .IsUnique(); + + b.ToTable("Installations"); + }); + + modelBuilder.Entity("Api.Database.Models.MissionDefinition", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("Comment") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("InspectionAreaId") + .HasColumnType("text"); + + b.Property("InspectionFrequency") + .HasColumnType("bigint"); + + b.Property("InstallationCode") + .IsRequired() + .HasColumnType("text"); + + b.Property("IsDeprecated") + .HasColumnType("boolean"); + + b.Property("LastSuccessfulRunId") + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("SourceId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("InspectionAreaId"); + + b.HasIndex("LastSuccessfulRunId"); + + b.HasIndex("SourceId"); + + b.ToTable("MissionDefinitions"); + }); + + modelBuilder.Entity("Api.Database.Models.MissionRun", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("Comment") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Description") + .HasMaxLength(450) + .HasColumnType("character varying(450)"); + + b.Property("DesiredStartTime") + .HasColumnType("timestamp with time zone"); + + b.Property("EndTime") + .HasColumnType("timestamp with time zone"); + + b.Property("EstimatedDuration") + .HasColumnType("bigint"); + + b.Property("InspectionAreaId") + .HasColumnType("text"); + + b.Property("InstallationCode") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("IsDeprecated") + .HasColumnType("boolean"); + + b.Property("IsarMissionId") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("MissionId") + .HasColumnType("text"); + + b.Property("MissionRunType") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("RobotId") + .IsRequired() + .HasColumnType("text"); + + b.Property("StartTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("StatusReason") + .HasMaxLength(450) + .HasColumnType("character varying(450)"); + + b.HasKey("Id"); + + b.HasIndex("InspectionAreaId"); + + b.HasIndex("RobotId"); + + b.ToTable("MissionRuns"); + }); + + modelBuilder.Entity("Api.Database.Models.MissionTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("EndTime") + .HasColumnType("timestamp with time zone"); + + b.Property("InspectionId") + .HasColumnType("text"); + + b.Property("IsarTaskId") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("MissionRunId") + .HasColumnType("text"); + + b.Property("PoseId") + .HasColumnType("integer"); + + b.Property("StartTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.Property("TagId") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("TagLink") + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("TaskOrder") + .HasColumnType("integer"); + + b.Property("Type") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("InspectionId"); + + b.HasIndex("MissionRunId"); + + b.ToTable("MissionTasks"); + }); + + modelBuilder.Entity("Api.Database.Models.Plant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("InstallationId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("PlantCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.HasKey("Id"); + + b.HasIndex("InstallationId"); + + b.HasIndex("PlantCode") + .IsUnique(); + + b.ToTable("Plants"); + }); + + modelBuilder.Entity("Api.Database.Models.Robot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("BatteryLevel") + .HasColumnType("real"); + + b.Property("CurrentInspectionAreaId") + .HasColumnType("text"); + + b.Property("CurrentInstallationId") + .IsRequired() + .HasColumnType("text"); + + b.Property("CurrentMissionId") + .HasColumnType("text"); + + b.Property("Deprecated") + .HasColumnType("boolean"); + + b.Property("FlotillaStatus") + .IsRequired() + .HasColumnType("text"); + + b.Property("Host") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("IsarConnected") + .HasColumnType("boolean"); + + b.Property("IsarId") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("MissionQueueFrozen") + .HasColumnType("boolean"); + + b.Property("ModelId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Port") + .HasColumnType("integer"); + + b.Property("PressureLevel") + .HasColumnType("real"); + + b.Property("RobotCapabilities") + .HasColumnType("text"); + + b.Property("SerialNumber") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b.Property("Status") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("CurrentInspectionAreaId"); + + b.HasIndex("CurrentInstallationId"); + + b.HasIndex("ModelId"); + + b.ToTable("Robots"); + }); + + modelBuilder.Entity("Api.Database.Models.RobotBatteryTimeseries", b => + { + b.Property("BatteryLevel") + .HasColumnType("real"); + + b.Property("MissionId") + .HasColumnType("text"); + + b.Property("RobotId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.ToTable("RobotBatteryTimeseries"); + }); + + modelBuilder.Entity("Api.Database.Models.RobotModel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("AverageDurationPerTag") + .HasColumnType("real"); + + b.Property("BatteryMissionStartThreshold") + .HasColumnType("real"); + + b.Property("BatteryWarningThreshold") + .HasColumnType("real"); + + b.Property("LowerPressureWarningThreshold") + .HasColumnType("real"); + + b.Property("Type") + .IsRequired() + .HasColumnType("text"); + + b.Property("UpperPressureWarningThreshold") + .HasColumnType("real"); + + b.HasKey("Id"); + + b.HasIndex("Type") + .IsUnique(); + + b.ToTable("RobotModels"); + }); + + modelBuilder.Entity("Api.Database.Models.RobotPoseTimeseries", b => + { + b.Property("MissionId") + .HasColumnType("text"); + + b.Property("OrientationW") + .HasColumnType("real"); + + b.Property("OrientationX") + .HasColumnType("real"); + + b.Property("OrientationY") + .HasColumnType("real"); + + b.Property("OrientationZ") + .HasColumnType("real"); + + b.Property("PositionX") + .HasColumnType("real"); + + b.Property("PositionY") + .HasColumnType("real"); + + b.Property("PositionZ") + .HasColumnType("real"); + + b.Property("RobotId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.ToTable("RobotPoseTimeseries"); + }); + + modelBuilder.Entity("Api.Database.Models.RobotPressureTimeseries", b => + { + b.Property("MissionId") + .HasColumnType("text"); + + b.Property("Pressure") + .HasColumnType("real"); + + b.Property("RobotId") + .IsRequired() + .HasColumnType("text"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.ToTable("RobotPressureTimeseries"); + }); + + modelBuilder.Entity("Api.Database.Models.Source", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("CustomMissionTasks") + .HasColumnType("text"); + + b.Property("SourceId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Sources"); + }); + + modelBuilder.Entity("Api.Database.Models.UserInfo", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b.Property("Oid") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("UserInfos"); + }); + + modelBuilder.Entity("Api.Services.MissionLoaders.TagInspectionMetadata", b => + { + b.Property("TagId") + .HasColumnType("text"); + + b.HasKey("TagId"); + + b.ToTable("TagInspectionMetadata"); + }); + + modelBuilder.Entity("Api.Database.Models.AccessRole", b => + { + b.HasOne("Api.Database.Models.Installation", "Installation") + .WithMany() + .HasForeignKey("InstallationId"); + + b.Navigation("Installation"); + }); + + modelBuilder.Entity("Api.Database.Models.Area", b => + { + b.HasOne("Api.Database.Models.Deck", "Deck") + .WithMany() + .HasForeignKey("DeckId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Api.Database.Models.DefaultLocalizationPose", "DefaultLocalizationPose") + .WithMany() + .HasForeignKey("DefaultLocalizationPoseId"); + + b.HasOne("Api.Database.Models.Installation", "Installation") + .WithMany() + .HasForeignKey("InstallationId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Api.Database.Models.Plant", "Plant") + .WithMany() + .HasForeignKey("PlantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.OwnsOne("Api.Database.Models.MapMetadata", "MapMetadata", b1 => + { + b1.Property("AreaId") + .HasColumnType("text"); + + b1.Property("MapName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b1.HasKey("AreaId"); + + b1.ToTable("Areas"); + + b1.WithOwner() + .HasForeignKey("AreaId"); + + b1.OwnsOne("Api.Database.Models.Boundary", "Boundary", b2 => + { + b2.Property("MapMetadataAreaId") + .HasColumnType("text"); + + b2.Property("X1") + .HasColumnType("double precision"); + + b2.Property("X2") + .HasColumnType("double precision"); + + b2.Property("Y1") + .HasColumnType("double precision"); + + b2.Property("Y2") + .HasColumnType("double precision"); + + b2.Property("Z1") + .HasColumnType("double precision"); + + b2.Property("Z2") + .HasColumnType("double precision"); + + b2.HasKey("MapMetadataAreaId"); + + b2.ToTable("Areas"); + + b2.WithOwner() + .HasForeignKey("MapMetadataAreaId"); + }); + + b1.OwnsOne("Api.Database.Models.TransformationMatrices", "TransformationMatrices", b2 => + { + b2.Property("MapMetadataAreaId") + .HasColumnType("text"); + + b2.Property("C1") + .HasColumnType("double precision"); + + b2.Property("C2") + .HasColumnType("double precision"); + + b2.Property("D1") + .HasColumnType("double precision"); + + b2.Property("D2") + .HasColumnType("double precision"); + + b2.HasKey("MapMetadataAreaId"); + + b2.ToTable("Areas"); + + b2.WithOwner() + .HasForeignKey("MapMetadataAreaId"); + }); + + b1.Navigation("Boundary") + .IsRequired(); + + b1.Navigation("TransformationMatrices") + .IsRequired(); + }); + + b.Navigation("Deck"); + + b.Navigation("DefaultLocalizationPose"); + + b.Navigation("Installation"); + + b.Navigation("MapMetadata") + .IsRequired(); + + b.Navigation("Plant"); + }); + + modelBuilder.Entity("Api.Database.Models.Deck", b => + { + b.HasOne("Api.Database.Models.DefaultLocalizationPose", "DefaultLocalizationPose") + .WithMany() + .HasForeignKey("DefaultLocalizationPoseId"); + + b.HasOne("Api.Database.Models.Installation", "Installation") + .WithMany() + .HasForeignKey("InstallationId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Api.Database.Models.Plant", "Plant") + .WithMany() + .HasForeignKey("PlantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("DefaultLocalizationPose"); + + b.Navigation("Installation"); + + b.Navigation("Plant"); + }); + + modelBuilder.Entity("Api.Database.Models.DefaultLocalizationPose", b => + { + b.OwnsOne("Api.Database.Models.Pose", "Pose", b1 => + { + b1.Property("DefaultLocalizationPoseId") + .HasColumnType("text"); + + b1.HasKey("DefaultLocalizationPoseId"); + + b1.ToTable("DefaultLocalizationPoses"); + + b1.WithOwner() + .HasForeignKey("DefaultLocalizationPoseId"); + + b1.OwnsOne("Api.Database.Models.Orientation", "Orientation", b2 => + { + b2.Property("PoseDefaultLocalizationPoseId") + .HasColumnType("text"); + + b2.Property("W") + .HasColumnType("real"); + + b2.Property("X") + .HasColumnType("real"); + + b2.Property("Y") + .HasColumnType("real"); + + b2.Property("Z") + .HasColumnType("real"); + + b2.HasKey("PoseDefaultLocalizationPoseId"); + + b2.ToTable("DefaultLocalizationPoses"); + + b2.WithOwner() + .HasForeignKey("PoseDefaultLocalizationPoseId"); + }); + + b1.OwnsOne("Api.Database.Models.Position", "Position", b2 => + { + b2.Property("PoseDefaultLocalizationPoseId") + .HasColumnType("text"); + + b2.Property("X") + .HasColumnType("real"); + + b2.Property("Y") + .HasColumnType("real"); + + b2.Property("Z") + .HasColumnType("real"); + + b2.HasKey("PoseDefaultLocalizationPoseId"); + + b2.ToTable("DefaultLocalizationPoses"); + + b2.WithOwner() + .HasForeignKey("PoseDefaultLocalizationPoseId"); + }); + + b1.Navigation("Orientation") + .IsRequired(); + + b1.Navigation("Position") + .IsRequired(); + }); + + b.Navigation("Pose") + .IsRequired(); + }); + + modelBuilder.Entity("Api.Database.Models.Inspection", b => + { + b.OwnsOne("Api.Database.Models.Position", "InspectionTarget", b1 => + { + b1.Property("InspectionId") + .HasColumnType("text"); + + b1.Property("X") + .HasColumnType("real"); + + b1.Property("Y") + .HasColumnType("real"); + + b1.Property("Z") + .HasColumnType("real"); + + b1.HasKey("InspectionId"); + + b1.ToTable("Inspections"); + + b1.WithOwner() + .HasForeignKey("InspectionId"); + }); + + b.Navigation("InspectionTarget") + .IsRequired(); + }); + + modelBuilder.Entity("Api.Database.Models.InspectionFinding", b => + { + b.HasOne("Api.Database.Models.Inspection", null) + .WithMany("InspectionFindings") + .HasForeignKey("InspectionId"); + }); + + modelBuilder.Entity("Api.Database.Models.MissionDefinition", b => + { + b.HasOne("Api.Database.Models.Deck", "InspectionArea") + .WithMany() + .HasForeignKey("InspectionAreaId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("Api.Database.Models.MissionRun", "LastSuccessfulRun") + .WithMany() + .HasForeignKey("LastSuccessfulRunId"); + + b.HasOne("Api.Database.Models.Source", "Source") + .WithMany() + .HasForeignKey("SourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("Api.Database.Models.MapMetadata", "Map", b1 => + { + b1.Property("MissionDefinitionId") + .HasColumnType("text"); + + b1.Property("MapName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b1.HasKey("MissionDefinitionId"); + + b1.ToTable("MissionDefinitions"); + + b1.WithOwner() + .HasForeignKey("MissionDefinitionId"); + + b1.OwnsOne("Api.Database.Models.Boundary", "Boundary", b2 => + { + b2.Property("MapMetadataMissionDefinitionId") + .HasColumnType("text"); + + b2.Property("X1") + .HasColumnType("double precision"); + + b2.Property("X2") + .HasColumnType("double precision"); + + b2.Property("Y1") + .HasColumnType("double precision"); + + b2.Property("Y2") + .HasColumnType("double precision"); + + b2.Property("Z1") + .HasColumnType("double precision"); + + b2.Property("Z2") + .HasColumnType("double precision"); + + b2.HasKey("MapMetadataMissionDefinitionId"); + + b2.ToTable("MissionDefinitions"); + + b2.WithOwner() + .HasForeignKey("MapMetadataMissionDefinitionId"); + }); + + b1.OwnsOne("Api.Database.Models.TransformationMatrices", "TransformationMatrices", b2 => + { + b2.Property("MapMetadataMissionDefinitionId") + .HasColumnType("text"); + + b2.Property("C1") + .HasColumnType("double precision"); + + b2.Property("C2") + .HasColumnType("double precision"); + + b2.Property("D1") + .HasColumnType("double precision"); + + b2.Property("D2") + .HasColumnType("double precision"); + + b2.HasKey("MapMetadataMissionDefinitionId"); + + b2.ToTable("MissionDefinitions"); + + b2.WithOwner() + .HasForeignKey("MapMetadataMissionDefinitionId"); + }); + + b1.Navigation("Boundary") + .IsRequired(); + + b1.Navigation("TransformationMatrices") + .IsRequired(); + }); + + b.Navigation("InspectionArea"); + + b.Navigation("LastSuccessfulRun"); + + b.Navigation("Map"); + + b.Navigation("Source"); + }); + + modelBuilder.Entity("Api.Database.Models.MissionRun", b => + { + b.HasOne("Api.Database.Models.Deck", "InspectionArea") + .WithMany() + .HasForeignKey("InspectionAreaId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("Api.Database.Models.Robot", "Robot") + .WithMany() + .HasForeignKey("RobotId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("InspectionArea"); + + b.Navigation("Robot"); + }); + + modelBuilder.Entity("Api.Database.Models.MissionTask", b => + { + b.HasOne("Api.Database.Models.Inspection", "Inspection") + .WithMany() + .HasForeignKey("InspectionId"); + + b.HasOne("Api.Database.Models.MissionRun", null) + .WithMany("Tasks") + .HasForeignKey("MissionRunId"); + + b.OwnsOne("Api.Services.Models.IsarZoomDescription", "IsarZoomDescription", b1 => + { + b1.Property("MissionTaskId") + .HasColumnType("text"); + + b1.Property("ObjectHeight") + .HasColumnType("double precision") + .HasAnnotation("Relational:JsonPropertyName", "objectHeight"); + + b1.Property("ObjectWidth") + .HasColumnType("double precision") + .HasAnnotation("Relational:JsonPropertyName", "objectWidth"); + + b1.HasKey("MissionTaskId"); + + b1.ToTable("MissionTasks"); + + b1.WithOwner() + .HasForeignKey("MissionTaskId"); + }); + + b.OwnsOne("Api.Database.Models.Pose", "RobotPose", b1 => + { + b1.Property("MissionTaskId") + .HasColumnType("text"); + + b1.HasKey("MissionTaskId"); + + b1.ToTable("MissionTasks"); + + b1.WithOwner() + .HasForeignKey("MissionTaskId"); + + b1.OwnsOne("Api.Database.Models.Orientation", "Orientation", b2 => + { + b2.Property("PoseMissionTaskId") + .HasColumnType("text"); + + b2.Property("W") + .HasColumnType("real"); + + b2.Property("X") + .HasColumnType("real"); + + b2.Property("Y") + .HasColumnType("real"); + + b2.Property("Z") + .HasColumnType("real"); + + b2.HasKey("PoseMissionTaskId"); + + b2.ToTable("MissionTasks"); + + b2.WithOwner() + .HasForeignKey("PoseMissionTaskId"); + }); + + b1.OwnsOne("Api.Database.Models.Position", "Position", b2 => + { + b2.Property("PoseMissionTaskId") + .HasColumnType("text"); + + b2.Property("X") + .HasColumnType("real"); + + b2.Property("Y") + .HasColumnType("real"); + + b2.Property("Z") + .HasColumnType("real"); + + b2.HasKey("PoseMissionTaskId"); + + b2.ToTable("MissionTasks"); + + b2.WithOwner() + .HasForeignKey("PoseMissionTaskId"); + }); + + b1.Navigation("Orientation") + .IsRequired(); + + b1.Navigation("Position") + .IsRequired(); + }); + + b.Navigation("Inspection"); + + b.Navigation("IsarZoomDescription"); + + b.Navigation("RobotPose") + .IsRequired(); + }); + + modelBuilder.Entity("Api.Database.Models.Plant", b => + { + b.HasOne("Api.Database.Models.Installation", "Installation") + .WithMany() + .HasForeignKey("InstallationId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Installation"); + }); + + modelBuilder.Entity("Api.Database.Models.Robot", b => + { + b.HasOne("Api.Database.Models.Deck", "CurrentInspectionArea") + .WithMany() + .HasForeignKey("CurrentInspectionAreaId"); + + b.HasOne("Api.Database.Models.Installation", "CurrentInstallation") + .WithMany() + .HasForeignKey("CurrentInstallationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Api.Database.Models.RobotModel", "Model") + .WithMany() + .HasForeignKey("ModelId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsMany("Api.Database.Models.DocumentInfo", "Documentation", b1 => + { + b1.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("text"); + + b1.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b1.Property("RobotId") + .IsRequired() + .HasColumnType("text"); + + b1.Property("Url") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("character varying(200)"); + + b1.HasKey("Id"); + + b1.HasIndex("RobotId"); + + b1.ToTable("DocumentInfo"); + + b1.WithOwner() + .HasForeignKey("RobotId"); + }); + + b.OwnsOne("Api.Database.Models.Pose", "Pose", b1 => + { + b1.Property("RobotId") + .HasColumnType("text"); + + b1.HasKey("RobotId"); + + b1.ToTable("Robots"); + + b1.WithOwner() + .HasForeignKey("RobotId"); + + b1.OwnsOne("Api.Database.Models.Orientation", "Orientation", b2 => + { + b2.Property("PoseRobotId") + .HasColumnType("text"); + + b2.Property("W") + .HasColumnType("real"); + + b2.Property("X") + .HasColumnType("real"); + + b2.Property("Y") + .HasColumnType("real"); + + b2.Property("Z") + .HasColumnType("real"); + + b2.HasKey("PoseRobotId"); + + b2.ToTable("Robots"); + + b2.WithOwner() + .HasForeignKey("PoseRobotId"); + }); + + b1.OwnsOne("Api.Database.Models.Position", "Position", b2 => + { + b2.Property("PoseRobotId") + .HasColumnType("text"); + + b2.Property("X") + .HasColumnType("real"); + + b2.Property("Y") + .HasColumnType("real"); + + b2.Property("Z") + .HasColumnType("real"); + + b2.HasKey("PoseRobotId"); + + b2.ToTable("Robots"); + + b2.WithOwner() + .HasForeignKey("PoseRobotId"); + }); + + b1.Navigation("Orientation") + .IsRequired(); + + b1.Navigation("Position") + .IsRequired(); + }); + + b.Navigation("CurrentInspectionArea"); + + b.Navigation("CurrentInstallation"); + + b.Navigation("Documentation"); + + b.Navigation("Model"); + + b.Navigation("Pose") + .IsRequired(); + }); + + modelBuilder.Entity("Api.Services.MissionLoaders.TagInspectionMetadata", b => + { + b.OwnsOne("Api.Services.Models.IsarZoomDescription", "ZoomDescription", b1 => + { + b1.Property("TagInspectionMetadataTagId") + .HasColumnType("text"); + + b1.Property("ObjectHeight") + .HasColumnType("double precision") + .HasAnnotation("Relational:JsonPropertyName", "objectHeight"); + + b1.Property("ObjectWidth") + .HasColumnType("double precision") + .HasAnnotation("Relational:JsonPropertyName", "objectWidth"); + + b1.HasKey("TagInspectionMetadataTagId"); + + b1.ToTable("TagInspectionMetadata"); + + b1.WithOwner() + .HasForeignKey("TagInspectionMetadataTagId"); + }); + + b.Navigation("ZoomDescription"); + }); + + modelBuilder.Entity("Api.Database.Models.Inspection", b => + { + b.Navigation("InspectionFindings"); + }); + + modelBuilder.Entity("Api.Database.Models.MissionRun", b => + { + b.Navigation("Tasks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/backend/api/Migrations/20241216130006_UseInspectionAreaInsteadOfAreaForLocalisation.cs b/backend/api/Migrations/20241216130006_UseInspectionAreaInsteadOfAreaForLocalisation.cs new file mode 100644 index 000000000..145f7ffa7 --- /dev/null +++ b/backend/api/Migrations/20241216130006_UseInspectionAreaInsteadOfAreaForLocalisation.cs @@ -0,0 +1,408 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Api.Migrations +{ + /// + public partial class UseInspectionAreaInsteadOfAreaForLocalisation : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_MissionDefinitions_Areas_AreaId", + table: "MissionDefinitions"); + + migrationBuilder.DropForeignKey( + name: "FK_MissionRuns_Areas_AreaId", + table: "MissionRuns"); + + migrationBuilder.DropForeignKey( + name: "FK_Robots_Areas_CurrentAreaId", + table: "Robots"); + + migrationBuilder.DropIndex( + name: "IX_MissionRuns_AreaId", + table: "MissionRuns"); + + migrationBuilder.DropIndex( + name: "IX_MissionDefinitions_AreaId", + table: "MissionDefinitions"); + + migrationBuilder.DropColumn( + name: "AreaId", + table: "MissionRuns"); + + migrationBuilder.DropColumn( + name: "Map_Boundary_X1", + table: "MissionRuns"); + + migrationBuilder.DropColumn( + name: "Map_Boundary_X2", + table: "MissionRuns"); + + migrationBuilder.DropColumn( + name: "Map_Boundary_Y1", + table: "MissionRuns"); + + migrationBuilder.DropColumn( + name: "Map_Boundary_Y2", + table: "MissionRuns"); + + migrationBuilder.DropColumn( + name: "Map_Boundary_Z1", + table: "MissionRuns"); + + migrationBuilder.DropColumn( + name: "Map_Boundary_Z2", + table: "MissionRuns"); + + migrationBuilder.DropColumn( + name: "Map_MapName", + table: "MissionRuns"); + + migrationBuilder.DropColumn( + name: "Map_TransformationMatrices_C1", + table: "MissionRuns"); + + migrationBuilder.DropColumn( + name: "Map_TransformationMatrices_C2", + table: "MissionRuns"); + + migrationBuilder.DropColumn( + name: "Map_TransformationMatrices_D1", + table: "MissionRuns"); + + migrationBuilder.DropColumn( + name: "Map_TransformationMatrices_D2", + table: "MissionRuns"); + + migrationBuilder.DropColumn( + name: "AreaId", + table: "MissionDefinitions"); + + migrationBuilder.RenameColumn( + name: "CurrentAreaId", + table: "Robots", + newName: "CurrentInspectionAreaId"); + + migrationBuilder.RenameIndex( + name: "IX_Robots_CurrentAreaId", + table: "Robots", + newName: "IX_Robots_CurrentInspectionAreaId"); + + migrationBuilder.AddColumn( + name: "InspectionAreaId", + table: "MissionRuns", + type: "text", + nullable: true); + + migrationBuilder.AddColumn( + name: "InspectionAreaId", + table: "MissionDefinitions", + type: "text", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_Boundary_X1", + table: "MissionDefinitions", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_Boundary_X2", + table: "MissionDefinitions", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_Boundary_Y1", + table: "MissionDefinitions", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_Boundary_Y2", + table: "MissionDefinitions", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_Boundary_Z1", + table: "MissionDefinitions", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_Boundary_Z2", + table: "MissionDefinitions", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_MapName", + table: "MissionDefinitions", + type: "character varying(200)", + maxLength: 200, + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_TransformationMatrices_C1", + table: "MissionDefinitions", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_TransformationMatrices_C2", + table: "MissionDefinitions", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_TransformationMatrices_D1", + table: "MissionDefinitions", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_TransformationMatrices_D2", + table: "MissionDefinitions", + type: "double precision", + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_MissionRuns_InspectionAreaId", + table: "MissionRuns", + column: "InspectionAreaId"); + + migrationBuilder.CreateIndex( + name: "IX_MissionDefinitions_InspectionAreaId", + table: "MissionDefinitions", + column: "InspectionAreaId"); + + migrationBuilder.AddForeignKey( + name: "FK_MissionDefinitions_Decks_InspectionAreaId", + table: "MissionDefinitions", + column: "InspectionAreaId", + principalTable: "Decks", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + + migrationBuilder.AddForeignKey( + name: "FK_MissionRuns_Decks_InspectionAreaId", + table: "MissionRuns", + column: "InspectionAreaId", + principalTable: "Decks", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + + migrationBuilder.AddForeignKey( + name: "FK_Robots_Decks_CurrentInspectionAreaId", + table: "Robots", + column: "CurrentInspectionAreaId", + principalTable: "Decks", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_MissionDefinitions_Decks_InspectionAreaId", + table: "MissionDefinitions"); + + migrationBuilder.DropForeignKey( + name: "FK_MissionRuns_Decks_InspectionAreaId", + table: "MissionRuns"); + + migrationBuilder.DropForeignKey( + name: "FK_Robots_Decks_CurrentInspectionAreaId", + table: "Robots"); + + migrationBuilder.DropIndex( + name: "IX_MissionRuns_InspectionAreaId", + table: "MissionRuns"); + + migrationBuilder.DropIndex( + name: "IX_MissionDefinitions_InspectionAreaId", + table: "MissionDefinitions"); + + migrationBuilder.DropColumn( + name: "InspectionAreaId", + table: "MissionRuns"); + + migrationBuilder.DropColumn( + name: "InspectionAreaId", + table: "MissionDefinitions"); + + migrationBuilder.DropColumn( + name: "Map_Boundary_X1", + table: "MissionDefinitions"); + + migrationBuilder.DropColumn( + name: "Map_Boundary_X2", + table: "MissionDefinitions"); + + migrationBuilder.DropColumn( + name: "Map_Boundary_Y1", + table: "MissionDefinitions"); + + migrationBuilder.DropColumn( + name: "Map_Boundary_Y2", + table: "MissionDefinitions"); + + migrationBuilder.DropColumn( + name: "Map_Boundary_Z1", + table: "MissionDefinitions"); + + migrationBuilder.DropColumn( + name: "Map_Boundary_Z2", + table: "MissionDefinitions"); + + migrationBuilder.DropColumn( + name: "Map_MapName", + table: "MissionDefinitions"); + + migrationBuilder.DropColumn( + name: "Map_TransformationMatrices_C1", + table: "MissionDefinitions"); + + migrationBuilder.DropColumn( + name: "Map_TransformationMatrices_C2", + table: "MissionDefinitions"); + + migrationBuilder.DropColumn( + name: "Map_TransformationMatrices_D1", + table: "MissionDefinitions"); + + migrationBuilder.DropColumn( + name: "Map_TransformationMatrices_D2", + table: "MissionDefinitions"); + + migrationBuilder.RenameColumn( + name: "CurrentInspectionAreaId", + table: "Robots", + newName: "CurrentAreaId"); + + migrationBuilder.RenameIndex( + name: "IX_Robots_CurrentInspectionAreaId", + table: "Robots", + newName: "IX_Robots_CurrentAreaId"); + + migrationBuilder.AddColumn( + name: "AreaId", + table: "MissionRuns", + type: "text", + nullable: false, + defaultValue: ""); + + migrationBuilder.AddColumn( + name: "Map_Boundary_X1", + table: "MissionRuns", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_Boundary_X2", + table: "MissionRuns", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_Boundary_Y1", + table: "MissionRuns", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_Boundary_Y2", + table: "MissionRuns", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_Boundary_Z1", + table: "MissionRuns", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_Boundary_Z2", + table: "MissionRuns", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_MapName", + table: "MissionRuns", + type: "character varying(200)", + maxLength: 200, + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_TransformationMatrices_C1", + table: "MissionRuns", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_TransformationMatrices_C2", + table: "MissionRuns", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_TransformationMatrices_D1", + table: "MissionRuns", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "Map_TransformationMatrices_D2", + table: "MissionRuns", + type: "double precision", + nullable: true); + + migrationBuilder.AddColumn( + name: "AreaId", + table: "MissionDefinitions", + type: "text", + nullable: false, + defaultValue: ""); + + migrationBuilder.CreateIndex( + name: "IX_MissionRuns_AreaId", + table: "MissionRuns", + column: "AreaId"); + + migrationBuilder.CreateIndex( + name: "IX_MissionDefinitions_AreaId", + table: "MissionDefinitions", + column: "AreaId"); + + migrationBuilder.AddForeignKey( + name: "FK_MissionDefinitions_Areas_AreaId", + table: "MissionDefinitions", + column: "AreaId", + principalTable: "Areas", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_MissionRuns_Areas_AreaId", + table: "MissionRuns", + column: "AreaId", + principalTable: "Areas", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Robots_Areas_CurrentAreaId", + table: "Robots", + column: "CurrentAreaId", + principalTable: "Areas", + principalColumn: "Id"); + } + } +} diff --git a/backend/api/Migrations/FlotillaDbContextModelSnapshot.cs b/backend/api/Migrations/FlotillaDbContextModelSnapshot.cs index d983d30c7..2a5a2472c 100644 --- a/backend/api/Migrations/FlotillaDbContextModelSnapshot.cs +++ b/backend/api/Migrations/FlotillaDbContextModelSnapshot.cs @@ -237,14 +237,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("text"); - b.Property("AreaId") - .IsRequired() - .HasColumnType("text"); - b.Property("Comment") .HasMaxLength(1000) .HasColumnType("character varying(1000)"); + b.Property("InspectionAreaId") + .HasColumnType("text"); + b.Property("InspectionFrequency") .HasColumnType("bigint"); @@ -269,7 +268,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("AreaId"); + b.HasIndex("InspectionAreaId"); b.HasIndex("LastSuccessfulRunId"); @@ -284,10 +283,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("text"); - b.Property("AreaId") - .IsRequired() - .HasColumnType("text"); - b.Property("Comment") .HasMaxLength(1000) .HasColumnType("character varying(1000)"); @@ -305,6 +300,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("EstimatedDuration") .HasColumnType("bigint"); + b.Property("InspectionAreaId") + .HasColumnType("text"); + b.Property("InstallationCode") .IsRequired() .HasMaxLength(200) @@ -346,7 +344,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("AreaId"); + b.HasIndex("InspectionAreaId"); b.HasIndex("RobotId"); @@ -449,7 +447,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("BatteryLevel") .HasColumnType("real"); - b.Property("CurrentAreaId") + b.Property("CurrentInspectionAreaId") .HasColumnType("text"); b.Property("CurrentInstallationId") @@ -511,7 +509,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("CurrentAreaId"); + b.HasIndex("CurrentInspectionAreaId"); b.HasIndex("CurrentInstallationId"); @@ -927,11 +925,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("Api.Database.Models.MissionDefinition", b => { - b.HasOne("Api.Database.Models.Area", "Area") + b.HasOne("Api.Database.Models.Deck", "InspectionArea") .WithMany() - .HasForeignKey("AreaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + .HasForeignKey("InspectionAreaId") + .OnDelete(DeleteBehavior.Restrict); b.HasOne("Api.Database.Models.MissionRun", "LastSuccessfulRun") .WithMany() @@ -943,30 +940,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.Navigation("Area"); - - b.Navigation("LastSuccessfulRun"); - - b.Navigation("Source"); - }); - - modelBuilder.Entity("Api.Database.Models.MissionRun", b => - { - b.HasOne("Api.Database.Models.Area", "Area") - .WithMany() - .HasForeignKey("AreaId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Api.Database.Models.Robot", "Robot") - .WithMany() - .HasForeignKey("RobotId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - b.OwnsOne("Api.Database.Models.MapMetadata", "Map", b1 => { - b1.Property("MissionRunId") + b1.Property("MissionDefinitionId") .HasColumnType("text"); b1.Property("MapName") @@ -974,16 +950,16 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(200) .HasColumnType("character varying(200)"); - b1.HasKey("MissionRunId"); + b1.HasKey("MissionDefinitionId"); - b1.ToTable("MissionRuns"); + b1.ToTable("MissionDefinitions"); b1.WithOwner() - .HasForeignKey("MissionRunId"); + .HasForeignKey("MissionDefinitionId"); b1.OwnsOne("Api.Database.Models.Boundary", "Boundary", b2 => { - b2.Property("MapMetadataMissionRunId") + b2.Property("MapMetadataMissionDefinitionId") .HasColumnType("text"); b2.Property("X1") @@ -1004,17 +980,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) b2.Property("Z2") .HasColumnType("double precision"); - b2.HasKey("MapMetadataMissionRunId"); + b2.HasKey("MapMetadataMissionDefinitionId"); - b2.ToTable("MissionRuns"); + b2.ToTable("MissionDefinitions"); b2.WithOwner() - .HasForeignKey("MapMetadataMissionRunId"); + .HasForeignKey("MapMetadataMissionDefinitionId"); }); b1.OwnsOne("Api.Database.Models.TransformationMatrices", "TransformationMatrices", b2 => { - b2.Property("MapMetadataMissionRunId") + b2.Property("MapMetadataMissionDefinitionId") .HasColumnType("text"); b2.Property("C1") @@ -1029,12 +1005,12 @@ protected override void BuildModel(ModelBuilder modelBuilder) b2.Property("D2") .HasColumnType("double precision"); - b2.HasKey("MapMetadataMissionRunId"); + b2.HasKey("MapMetadataMissionDefinitionId"); - b2.ToTable("MissionRuns"); + b2.ToTable("MissionDefinitions"); b2.WithOwner() - .HasForeignKey("MapMetadataMissionRunId"); + .HasForeignKey("MapMetadataMissionDefinitionId"); }); b1.Navigation("Boundary") @@ -1044,10 +1020,30 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired(); }); - b.Navigation("Area"); + b.Navigation("InspectionArea"); + + b.Navigation("LastSuccessfulRun"); b.Navigation("Map"); + b.Navigation("Source"); + }); + + modelBuilder.Entity("Api.Database.Models.MissionRun", b => + { + b.HasOne("Api.Database.Models.Deck", "InspectionArea") + .WithMany() + .HasForeignKey("InspectionAreaId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("Api.Database.Models.Robot", "Robot") + .WithMany() + .HasForeignKey("RobotId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("InspectionArea"); + b.Navigation("Robot"); }); @@ -1169,9 +1165,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("Api.Database.Models.Robot", b => { - b.HasOne("Api.Database.Models.Area", "CurrentArea") + b.HasOne("Api.Database.Models.Deck", "CurrentInspectionArea") .WithMany() - .HasForeignKey("CurrentAreaId"); + .HasForeignKey("CurrentInspectionAreaId"); b.HasOne("Api.Database.Models.Installation", "CurrentInstallation") .WithMany() @@ -1281,7 +1277,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .IsRequired(); }); - b.Navigation("CurrentArea"); + b.Navigation("CurrentInspectionArea"); b.Navigation("CurrentInstallation"); diff --git a/backend/api/Services/MissionDefinitionService.cs b/backend/api/Services/MissionDefinitionService.cs index 26a7c8a05..1a4a2e113 100644 --- a/backend/api/Services/MissionDefinitionService.cs +++ b/backend/api/Services/MissionDefinitionService.cs @@ -166,17 +166,17 @@ private IQueryable GetMissionDefinitionsWithSubModels(bool re var accessibleInstallationCodes = accessRoleService.GetAllowedInstallationCodes(); var query = context.MissionDefinitions .Include(missionDefinition => missionDefinition.InspectionArea) - .ThenInclude(deck => deck.Plant) + .ThenInclude(deck => deck!.Plant) .ThenInclude(plant => plant.Installation) .Include(missionDefinition => missionDefinition.InspectionArea) - .ThenInclude(area => area.Installation) + .ThenInclude(area => area!.Installation) .Include(missionDefinition => missionDefinition.Source) .Include(missionDefinition => missionDefinition.LastSuccessfulRun) .ThenInclude(missionRun => missionRun != null ? missionRun.Tasks : null)! .ThenInclude(missionTask => missionTask.Inspection) .ThenInclude(inspection => inspection != null ? inspection.InspectionFindings : null) .Include(missionDefinition => missionDefinition.InspectionArea) - .ThenInclude(deck => deck.DefaultLocalizationPose) + .ThenInclude(deck => deck!.DefaultLocalizationPose) .ThenInclude(defaultLocalizationPose => defaultLocalizationPose != null ? defaultLocalizationPose.Pose : null) .Where((m) => m.InspectionArea == null || accessibleInstallationCodes.Result.Contains(m.InspectionArea.Installation.InstallationCode.ToUpper())); return readOnly ? query.AsNoTracking() : query.AsTracking(); diff --git a/backend/api/Services/MissionSchedulingService.cs b/backend/api/Services/MissionSchedulingService.cs index 94387a256..203862386 100644 --- a/backend/api/Services/MissionSchedulingService.cs +++ b/backend/api/Services/MissionSchedulingService.cs @@ -74,11 +74,11 @@ public async Task StartNextMissionRunIfSystemIsAvailable(Robot robot) return; } - if (robot.CurrentInspectionArea == null) + if (robot.CurrentInspectionArea == null && missionRun.InspectionArea != null) { await robotService.UpdateCurrentInspectionArea(robot.Id, missionRun.InspectionArea.Id); } - else if (!await localizationService.RobotIsOnSameDeckAsMission(robot.Id, missionRun.InspectionArea.Id)) + else if (!await localizationService.RobotIsOnSameDeckAsMission(robot.Id, missionRun.InspectionArea!.Id)) { logger.LogError("Robot {RobotId} is not on the same deck as the mission run {MissionRunId}. Aborting all mission runs", robot.Id, missionRun.Id); try { await AbortAllScheduledMissions(robot.Id, "Aborted: Robot was at different deck"); } diff --git a/backend/api/Services/Models/IsarMissionDefinition.cs b/backend/api/Services/Models/IsarMissionDefinition.cs index 63aab9141..ed22db36e 100644 --- a/backend/api/Services/Models/IsarMissionDefinition.cs +++ b/backend/api/Services/Models/IsarMissionDefinition.cs @@ -35,9 +35,12 @@ public IsarMissionDefinition(MissionRun missionRun, bool includeStartPose = fals { Name = missionRun.Name; Tasks = missionRun.Tasks.Select(task => new IsarTaskDefinition(task, missionRun, mapName)).ToList(); - StartPose = includeStartPose && missionRun.InspectionArea.DefaultLocalizationPose != null ? new IsarPose(missionRun.InspectionArea.DefaultLocalizationPose.Pose) : null; - Undock = includeStartPose && missionRun.InspectionArea.DefaultLocalizationPose != null && missionRun.InspectionArea.DefaultLocalizationPose.DockingEnabled; - Dock = missionRun.InspectionArea.DefaultLocalizationPose != null && missionRun.InspectionArea.DefaultLocalizationPose.DockingEnabled && missionRun.IsReturnHomeMission(); + if (missionRun.InspectionArea != null) + { + StartPose = includeStartPose && missionRun.InspectionArea.DefaultLocalizationPose != null ? new IsarPose(missionRun.InspectionArea.DefaultLocalizationPose.Pose) : null; + Undock = includeStartPose && missionRun.InspectionArea.DefaultLocalizationPose != null && missionRun.InspectionArea.DefaultLocalizationPose.DockingEnabled; + Dock = missionRun.InspectionArea.DefaultLocalizationPose != null && missionRun.InspectionArea.DefaultLocalizationPose.DockingEnabled && missionRun.IsReturnHomeMission(); + } } }