Skip to content

Commit

Permalink
Add LocalizationPose to Deck
Browse files Browse the repository at this point in the history
  • Loading branch information
oysand committed Aug 31, 2023
1 parent 5a704b7 commit ae73818
Show file tree
Hide file tree
Showing 18 changed files with 1,824 additions and 18 deletions.
39 changes: 29 additions & 10 deletions backend/api.test/EndpointTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ public void Dispose()
}
};


var installationQuery = new CreateInstallationQuery
{
InstallationCode = installationCode,
Expand All @@ -144,7 +145,8 @@ public void Dispose()
{
InstallationCode = installationCode,
PlantCode = plantCode,
Name = deckName
Name = deckName,
LocalizationPose = testPose
};

var areaQuery = new CreateAreaQuery
Expand Down Expand Up @@ -217,9 +219,9 @@ public async Task MissionsTest()
Assert.True(robots != null);
var robot = robots[0];
string robotId = robot.Id;
string testInstallation = "TestInstallationStartMissionTest";
string testPlant = "TestPlantStartMissionTest";
string testDeck = "TestDeckStartMissionTest";
string testInstallation = "testInstallationStartMissionTest";
string testPlant = "testPlantStartMissionTest";
string testDeck = "testDeckStartMissionTest";
string testArea = "testAreaStartMissionTest";

await PopulateAreaDb(testInstallation, testPlant, testDeck, testArea);
Expand Down Expand Up @@ -327,7 +329,7 @@ public async Task StartMissionTest()
Assert.True(robots != null);
var robot = robots[0];
string robotId = robot.Id;
string testInstallation = "TestInstallationStartMissionTest";
string testInstallation = "testInstallationStartMissionTest";
string testArea = "testAreaStartMissionTest";
int echoMissionId = 95;

Expand Down Expand Up @@ -359,8 +361,8 @@ public async Task StartMissionTest()
public async Task AreaTest()
{
// Arrange
string testInstallation = "TestInstallationAreaTest";
string testPlant = "TestPlantAreaTest";
string testInstallation = "testInstallationAreaTest";
string testPlant = "testPlantAreaTest";
string testDeck = "testDeckAreaTest";
string testArea = "testAreaAreaTest";
string installationUrl = $"/installations";
Expand All @@ -383,7 +385,23 @@ public async Task AreaTest()
W = 1
}
};
var testLocalizationPose = new Pose
{
Position = new Position
{
X = 1,
Y = 2,
Z = 3
},
Orientation = new Orientation
{
X = 0,
Y = 0,
Z = 0,
W = 1
}

};
var installationQuery = new CreateInstallationQuery
{
InstallationCode = testInstallation,
Expand All @@ -401,7 +419,8 @@ public async Task AreaTest()
{
InstallationCode = testInstallation,
PlantCode = testPlant,
Name = testDeck
Name = testDeck,
LocalizationPose = testLocalizationPose
};

var areaQuery = new CreateAreaQuery
Expand Down Expand Up @@ -456,8 +475,8 @@ public async Task AreaTest()
public async Task GetMissionsInAreaTest()
{
// Arrange
string testInstallation = "TestInstallationMissionsInAreaTest";
string testPlant = "TestPlantMissionsInAreaTest";
string testInstallation = "testInstallationMissionsInAreaTest";
string testPlant = "testPlantMissionsInAreaTest";
string testDeck = "testDeckMissionsInAreaTest";
string testArea = "testAreaMissionsInAreaTest";
string testMissionName = "testMissionInAreaTest";
Expand Down
3 changes: 2 additions & 1 deletion backend/api.test/Services/MissionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ public async Task Create()
{
Plant = testPlant,
Installation = testInstallation,
Name = "testDeck"
Name = "testDeck",
LocalizationPose = new LocalizationPose()
},
Installation = testInstallation,
Plant = testPlant,
Expand Down
59 changes: 58 additions & 1 deletion backend/api/Controllers/DeckController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class DeckController : ControllerBase
private readonly IDeckService _deckService;
private readonly IInstallationService _installationService;
private readonly IPlantService _plantService;
private readonly ILocalizationPoseService _localizationPoseService;

private readonly IMapService _mapService;

Expand All @@ -23,14 +24,16 @@ public DeckController(
IMapService mapService,
IDeckService deckService,
IInstallationService installationService,
IPlantService plantService
IPlantService plantService,
ILocalizationPoseService localizationPoseService
)
{
_logger = logger;
_mapService = mapService;
_deckService = deckService;
_installationService = installationService;
_plantService = plantService;
_localizationPoseService = localizationPoseService;
}

/// <summary>
Expand Down Expand Up @@ -88,6 +91,60 @@ public async Task<ActionResult<Deck>> GetDeckById([FromRoute] string id)

}

/// <summary>
/// Add or update the localization pose to a deck
/// </summary>
/// <remarks>
/// <para> This query updates an existing deck with a new localization pose </para>
/// </remarks>
[HttpPut]
[Route("add-localization-pose/{deckId}")]
[Authorize(Roles = Role.Admin)]
[ProducesResponseType(typeof(Deck), StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<Deck>> AddLocalizationPoseToDeck([FromRoute] string deckId, [FromBody] Pose localizationPose)
{
_logger.LogInformation("Updating localization pose to an existing deck");
try
{

var existingDeck = await _deckService.ReadById(deckId);
if (existingDeck == null)
{
_logger.LogInformation("Could not find the deck");
return BadRequest($"Deck already exists");
}


if (existingDeck.LocalizationPose != null)
{
_logger.LogInformation("Removing old localization pose");
var oldLocalizationPose = await _localizationPoseService.Delete(existingDeck.LocalizationPose.Id);
}

var newLocalizationPose = await _localizationPoseService.Create(localizationPose);
existingDeck.LocalizationPose = newLocalizationPose;
var updateDeck = await _deckService.Update(existingDeck);
_logger.LogInformation(
"Succesfully created new deck with id '{deckId}'",
updateDeck.Id
);
return CreatedAtAction(
nameof(GetDeckById),
new { id = updateDeck.Id },
updateDeck
);
}
catch (Exception e)
{
_logger.LogError(e, "Error while adding a localization pose to deck");
throw;
}
}

/// <summary>
/// Add a new deck
/// </summary>
Expand Down
146 changes: 146 additions & 0 deletions backend/api/Controllers/LocalizationPoseController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
using Api.Controllers.Models;
using Api.Database.Models;
using Api.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Api.Controllers
{
[ApiController]
[Route("localization-pose")]
public class LocalizationPoseController : ControllerBase
{
private readonly ILocalizationPoseService _localizationPoseService;
private readonly IInstallationService _installationService;
private readonly IPlantService _plantService;

private readonly IMapService _mapService;

private readonly ILogger<LocalizationPoseController> _logger;

public LocalizationPoseController(
ILogger<LocalizationPoseController> logger,
IMapService mapService,
ILocalizationPoseService localizationPoseService,
IInstallationService installationService,
IPlantService plantService
)
{
_logger = logger;
_mapService = mapService;
_localizationPoseService = localizationPoseService;
_installationService = installationService;
_plantService = plantService;
}

/// <summary>
/// List all decks in the Flotilla database
/// </summary>
/// <remarks>
/// <para> This query gets all decks </para>
/// </remarks>
[HttpGet]
[Authorize(Roles = Role.Any)]
[ProducesResponseType(typeof(IList<LocalizationPose>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<IList<LocalizationPose>>> GetLocalizationPoses()
{
try
{
var decks = await _localizationPoseService.ReadAll();
return Ok(decks);
}
catch (Exception e)
{
_logger.LogError(e, "Error during GET of decks from database");
throw;
}
}

/// <summary>
/// Lookup localization pose by specified id.
/// </summary>
[HttpGet]
[Authorize(Roles = Role.Any)]
[Route("{id}")]
[ProducesResponseType(typeof(LocalizationPose), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<LocalizationPose>> GetLocalizationPoseById([FromRoute] string id)
{
try
{
var localizationPose = await _localizationPoseService.ReadById(id);
if (localizationPose == null)
return NotFound($"Could not find localization pose with id {id}");
return Ok(localizationPose);
}
catch (Exception e)
{
_logger.LogError(e, "Error during GET of localization pose from database");
throw;
}

}

/// <summary>
/// Add a new localization pose
/// </summary>
/// <remarks>
/// <para> This query adds a new localization pose to the database </para>
/// </remarks>
[HttpPost]
[Authorize(Roles = Role.Admin)]
[ProducesResponseType(typeof(LocalizationPose), StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<LocalizationPose>> Create([FromBody] CreateLocalizationPoseQuery localizationPoseQuery)
{
_logger.LogInformation("Creating new localization pose");
try
{
var newLocalizationPose = await _localizationPoseService.Create(localizationPoseQuery.Pose);
_logger.LogInformation(
"Succesfully created new localization pose with id '{deckId}'",
newLocalizationPose.Id
);
return CreatedAtAction(
nameof(GetLocalizationPoseById),
new { id = newLocalizationPose.Id },
newLocalizationPose
);
}
catch (Exception e)
{
_logger.LogError(e, "Error while creating new localization pose");
throw;
}
}

/// <summary>
/// Deletes the localization pose with the specified id from the database.
/// </summary>
[HttpDelete]
[Authorize(Roles = Role.Admin)]
[Route("{id}")]
[ProducesResponseType(typeof(LocalizationPose), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public async Task<ActionResult<LocalizationPose>> DeleteLocalizationPose([FromRoute] string id)
{
var localizationPose = await _localizationPoseService.Delete(id);
if (localizationPose is null)
return NotFound($"LocalizationPose with id {id} not found");
return Ok(localizationPose);
}
}
}
10 changes: 10 additions & 0 deletions backend/api/Controllers/Models/AddLocalizationPoseToDeckQuery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Api.Database.Models;

namespace Api.Controllers.Models
{
public struct AddLocalizationPoseToDeckQuery
{
public string DeckId { get; set; }
public Pose LocalizationPose { get; set; }
}
}
5 changes: 4 additions & 1 deletion backend/api/Controllers/Models/CreateDeckQuery.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
namespace Api.Controllers.Models
using Api.Database.Models;

namespace Api.Controllers.Models
{
public struct CreateDeckQuery
{
public string InstallationCode { get; set; }
public string PlantCode { get; set; }
public string Name { get; set; }
public Pose? LocalizationPose { get; set; }
}
}
9 changes: 9 additions & 0 deletions backend/api/Controllers/Models/CreateLocalizationPoseQuery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Api.Database.Models;

namespace Api.Controllers.Models
{
public struct CreateLocalizationPoseQuery
{
public Pose Pose { get; set; }
}
}
6 changes: 6 additions & 0 deletions backend/api/Database/Context/FlotillaDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class FlotillaDbContext : DbContext
public DbSet<Area> Areas => Set<Area>();
public DbSet<Source> Sources => Set<Source>();
public DbSet<SafePosition> SafePositions => Set<SafePosition>();
public DbSet<LocalizationPose> LocalizationPoses => Set<LocalizationPose>();

public FlotillaDbContext(DbContextOptions options) : base(options) { }

Expand Down Expand Up @@ -75,6 +76,11 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.Entity<Deck>().HasOne(d => d.Plant).WithMany();
modelBuilder.Entity<Deck>().HasOne(d => d.Installation).WithMany();
modelBuilder.Entity<Plant>().HasOne(a => a.Installation).WithMany();
modelBuilder.Entity<LocalizationPose>().OwnsOne(s => s.Pose, poseBuilder =>
{
poseBuilder.OwnsOne(pose => pose.Position);
poseBuilder.OwnsOne(pose => pose.Orientation);
});

modelBuilder.Entity<SafePosition>().OwnsOne(s => s.Pose, poseBuilder =>
{
Expand Down
Loading

0 comments on commit ae73818

Please sign in to comment.