Initial commit
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
namespace RobotNet10.FleetManager.Script;
|
||||
|
||||
/// <summary>
|
||||
/// Service interface for managing map layouts, nodes, and stations.
|
||||
/// Provides methods to retrieve map elements (nodes, stations) and actions from the layout database.
|
||||
/// </summary>
|
||||
public interface ILayoutManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves a station from the specified map by its name.
|
||||
/// </summary>
|
||||
/// <param name="layout">The identifier of the map/layout. Cannot be null or empty.</param>
|
||||
/// <param name="version">The version of the map. Cannot be null or empty.</param>
|
||||
/// <param name="level">The level identifier within the map. Cannot be null or empty.</param>
|
||||
/// <param name="name">The name of the station to retrieve. Cannot be null or empty.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous operation.
|
||||
/// The task result contains the <see cref="IStation"/> matching the specified name within the given map,
|
||||
/// or throws an exception if no such station exists.
|
||||
/// </returns>
|
||||
Task<IStation> GetStation(string layout, string version, string level, string name);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a node from the specified map by its name.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method performs an asynchronous operation to locate a node within the specified map.
|
||||
/// Ensure that the map and name parameters are valid and non-empty before calling this method.
|
||||
/// </remarks>
|
||||
/// <param name="layout">The identifier of the map from which to retrieve the node. Cannot be null or empty.</param>
|
||||
/// <param name="version">The version of the map. Cannot be null or empty.</param>
|
||||
/// <param name="level">The level identifier within the map. Cannot be null or empty.</param>
|
||||
/// <param name="name">The name of the node to retrieve. Cannot be null or empty.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous operation.
|
||||
/// The task result contains the <see cref="INode"/> matching the specified name within the given map,
|
||||
/// or throws an exception if no such node exists.
|
||||
/// </returns>
|
||||
Task<INode> GetNode(string layout, string version, string level, string name);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a VDA5050 action configuration for a specific element (node or station) in the map.
|
||||
/// </summary>
|
||||
/// <param name="layout">The identifier of the map/layout. Cannot be null or empty.</param>
|
||||
/// <param name="version">The version of the map. Cannot be null or empty.</param>
|
||||
/// <param name="level">The level identifier within the map. Cannot be null or empty.</param>
|
||||
/// <param name="name">The name of the element (node or station) for which to retrieve the action. Cannot be null or empty.</param>
|
||||
/// <param name="robotId">The identifier of the robot that will execute the action. Used for robot-specific action configuration. Cannot be null or empty.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous operation.
|
||||
/// The task result contains the VDA5050 <see cref="RobotNet.VDA5050.InstantAction.Action"/> configured for the specified element and robot,
|
||||
/// or throws an exception if no such action exists.
|
||||
/// </returns>
|
||||
Task<RobotNet.VDA5050.InstantAction.Action> GetAction(string layout, string version, string level, string name, string robotId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a node (waypoint) in the map layout.
|
||||
/// Nodes define points where robots can navigate to or pass through.
|
||||
/// Conforms to VDMA LIF (Logistics Interface Format) standard.
|
||||
/// </summary>
|
||||
public interface INode
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the unique identifier of the node.
|
||||
/// </summary>
|
||||
public Guid Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the parent map identifier that contains this node.
|
||||
/// </summary>
|
||||
public Guid MapId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the node identifier (VDMA LIF: nodeId).
|
||||
/// This is a required field and must be unique within the level.
|
||||
/// </summary>
|
||||
public string NodeId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the node name (VDMA LIF: nodeName).
|
||||
/// This is an optional human-readable name for the node.
|
||||
/// </summary>
|
||||
public string? NodeName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the node description (VDMA LIF: nodeDescription).
|
||||
/// This is an optional description providing additional information about the node.
|
||||
/// </summary>
|
||||
public string? NodeDescription { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the X coordinate of the node position in meters (VDMA LIF: nodePosition.x).
|
||||
/// This is a required field.
|
||||
/// </summary>
|
||||
public double X { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Y coordinate of the node position in meters (VDMA LIF: nodePosition.y).
|
||||
/// This is a required field.
|
||||
/// </summary>
|
||||
public double Y { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a station (workstation or loading/unloading point) in the map layout.
|
||||
/// Stations are locations where robots can perform pick or drop operations.
|
||||
/// Conforms to VDMA LIF (Logistics Interface Format) standard.
|
||||
/// </summary>
|
||||
public interface IStation
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the unique identifier of the station.
|
||||
/// </summary>
|
||||
Guid Id { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the identifier of the map that contains this station.
|
||||
/// </summary>
|
||||
Guid MapId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the identifiers of the nodes that this station is linked to.
|
||||
/// A station can be associated with one or more nodes for navigation purposes.
|
||||
/// </summary>
|
||||
Guid[] NodeId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the station identifier (VDMA LIF: stationId).
|
||||
/// This is a required field and must be unique within the level.
|
||||
/// </summary>
|
||||
public string StationId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the station name (VDMA LIF: stationName).
|
||||
/// This is an optional human-readable name for the station.
|
||||
/// </summary>
|
||||
public string? StationName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the station description (VDMA LIF: stationDescription).
|
||||
/// This is an optional description providing additional information about the station.
|
||||
/// </summary>
|
||||
public string? StationDescription { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the station height in meters (VDMA LIF: stationHeight).
|
||||
/// This is an optional field indicating the height of the station platform.
|
||||
/// </summary>
|
||||
public double? StationHeight { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the X coordinate of the station position in meters (VDMA LIF: stationPosition.x).
|
||||
/// This is a required field.
|
||||
/// </summary>
|
||||
public double X { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Y coordinate of the station position in meters (VDMA LIF: stationPosition.y).
|
||||
/// This is a required field.
|
||||
/// </summary>
|
||||
public double Y { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the theta orientation angle in radians (VDMA LIF: stationPosition.theta).
|
||||
/// This is an optional field indicating the orientation of the station.
|
||||
/// Range: [-Pi ... Pi]
|
||||
/// </summary>
|
||||
public double? Theta { get; }
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
namespace RobotNet10.FleetManager.Script;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the action types that can be performed at a station.
|
||||
/// </summary>
|
||||
public enum StationAction
|
||||
{
|
||||
/// <summary>
|
||||
/// Pick up a load from the station.
|
||||
/// </summary>
|
||||
Pick,
|
||||
|
||||
/// <summary>
|
||||
/// Drop off a load at the station.
|
||||
/// </summary>
|
||||
Drop,
|
||||
|
||||
/// <summary>
|
||||
/// No action - robot moves to station without performing any load operation.
|
||||
/// </summary>
|
||||
None
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interface for controlling an Autonomous Mobile Robot (AMR).
|
||||
/// Provides methods to move the robot, execute actions, and query its current state.
|
||||
/// </summary>
|
||||
public interface IRobot
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the unique identifier of the robot (serial number or unique identifier).
|
||||
/// </summary>
|
||||
string RobotId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display name of the robot.
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the robot model identifier.
|
||||
/// </summary>
|
||||
Guid ModelId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the map identifier where the robot is currently operating, or <see langword="null"/> if not assigned to a map.
|
||||
/// </summary>
|
||||
Guid? MapId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current state of the robot, including position, battery, loads, and operational status.
|
||||
/// </summary>
|
||||
RobotState State { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Moves the robot to a target node on the map without performing any end action.
|
||||
/// </summary>
|
||||
/// <param name="nodeName">The name of the target node. Cannot be null or empty.</param>
|
||||
/// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous operation.
|
||||
/// The task result contains a <see cref="RobotResult"/> indicating success or failure of the movement command.
|
||||
/// </returns>
|
||||
Task<RobotResult> MoveToNode(string nodeName, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Moves the robot to a target node with a specific orientation at the endpoint.
|
||||
/// </summary>
|
||||
/// <param name="nodeName">The name of the target node. Cannot be null or empty.</param>
|
||||
/// <param name="lastAngle">The required orientation angle in radians at the endpoint. Range: [-Pi ... Pi].</param>
|
||||
/// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous operation.
|
||||
/// The task result contains a <see cref="RobotResult"/> indicating success or failure of the movement command.
|
||||
/// </returns>
|
||||
Task<RobotResult> MoveToNode(string nodeName, double lastAngle, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Moves the robot to a target station node and executes the specified action (pick, drop, or none).
|
||||
/// </summary>
|
||||
/// <param name="nodeName">The name of the target station node. Cannot be null or empty.</param>
|
||||
/// <param name="action">The action to perform at the station: <see cref="StationAction.Pick"/>, <see cref="StationAction.Drop"/>, or <see cref="StationAction.None"/>.</param>
|
||||
/// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous operation.
|
||||
/// The task result contains a <see cref="RobotResult"/> indicating success or failure of the movement and action execution.
|
||||
/// </returns>
|
||||
Task<RobotResult> MoveToStation(string nodeName, StationAction action, CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
/// Aborts or cancels the ongoing robot movement action, if one exists.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous operation.
|
||||
/// </returns>
|
||||
Task AbortMovement();
|
||||
|
||||
/// <summary>
|
||||
/// Immediately executes an instant action on the robot, bypassing any waiting period.
|
||||
/// Instant actions are executed immediately without requiring the robot to be at a specific location.
|
||||
/// </summary>
|
||||
/// <param name="action">The VDA5050 instant action to execute. Cannot be null.</param>
|
||||
/// <param name="cancellationToken">A cancellation token that can be used to cancel the operation.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous operation.
|
||||
/// The task result contains a <see cref="RobotResult"/> indicating success or failure of the action execution.
|
||||
/// </returns>
|
||||
Task<RobotResult> Execute(RobotNet.VDA5050.InstantAction.Action action, CancellationToken cancellationToken);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace RobotNet10.FleetManager.Script;
|
||||
|
||||
/// <summary>
|
||||
/// Robot management service interface for FleetManager scripts.
|
||||
/// Provides methods to retrieve, query, and manage robots in the fleet.
|
||||
/// </summary>
|
||||
public interface IRobotManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieves a robot controller by its unique identifier.
|
||||
/// </summary>
|
||||
/// <param name="robotId">The unique identifier of the robot. Cannot be null or empty.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous operation.
|
||||
/// The task result contains the <see cref="IRobot"/> instance if found, or <see langword="null"/> if the robot does not exist or is not available.
|
||||
/// </returns>
|
||||
Task<IRobot?> GetRobotById(string robotId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current state of a robot by its identifier.
|
||||
/// </summary>
|
||||
/// <param name="robotId">The unique identifier of the robot. Cannot be null or empty.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous operation.
|
||||
/// The task result contains the <see cref="RobotState"/> if the robot is found and connected, or <see langword="null"/> otherwise.
|
||||
/// </returns>
|
||||
Task<RobotState?> GetRobotState(string robotId);
|
||||
|
||||
/// <summary>
|
||||
/// Searches for robots on a specific map by layout, version, level, and model.
|
||||
/// </summary>
|
||||
/// <param name="layout">The identifier of the map/layout. Cannot be null or empty.</param>
|
||||
/// <param name="version">The version of the map. Cannot be null or empty.</param>
|
||||
/// <param name="level">The level identifier within the map. Cannot be null or empty.</param>
|
||||
/// <param name="model">The robot model identifier to filter by. Cannot be null or empty.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous operation.
|
||||
/// The task result contains a collection of robot IDs that match the specified criteria.
|
||||
/// </returns>
|
||||
Task<IEnumerable<string>> SearchRobots(string layout, string version, string level, string model);
|
||||
|
||||
/// <summary>
|
||||
/// Searches for robots on a specific map with additional state-based filtering conditions.
|
||||
/// </summary>
|
||||
/// <param name="layout">The identifier of the map/layout. Cannot be null or empty.</param>
|
||||
/// <param name="version">The version of the map. Cannot be null or empty.</param>
|
||||
/// <param name="level">The level identifier within the map. Cannot be null or empty.</param>
|
||||
/// <param name="model">The robot model identifier to filter by. Cannot be null or empty.</param>
|
||||
/// <param name="expr">A lambda expression that defines additional filtering conditions based on <see cref="RobotState"/>.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous operation.
|
||||
/// The task result contains a collection of robot IDs that match all specified criteria including the state filter.
|
||||
/// </returns>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Find all ready robots with battery voltage above 24V
|
||||
/// var robots = await RobotManager.SearchRobots("layout1", "v1", "level1", "model1", tate => state.IsReady, state.Voltage > 24.0);
|
||||
/// </code>
|
||||
/// </example>
|
||||
Task<IEnumerable<string>> SearchRobots(string layout, string version, string level, string model, Expression<Func<RobotState, bool>> expr);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current order status of a robot.
|
||||
/// </summary>
|
||||
/// <param name="robotId">The unique identifier of the robot. Cannot be null or empty.</param>
|
||||
/// <returns>
|
||||
/// A task that represents the asynchronous operation.
|
||||
/// The task result contains the <see cref="RobotOrderStatus"/> indicating the current order processing state of the robot.
|
||||
/// </returns>
|
||||
Task<RobotOrderStatus> GetRobotOrderStatus(string robotId);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Shared\RobotNet.VDA5050\RobotNet.VDA5050.csproj" />
|
||||
<ProjectReference Include="..\..\Shared\RobotNet10.Shared\RobotNet10.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,32 @@
|
||||
namespace RobotNet10.FleetManager.Script;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the current order processing status of a robot.
|
||||
/// </summary>
|
||||
public enum RobotOrderStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// The robot's current order has encountered an error and cannot be completed.
|
||||
/// </summary>
|
||||
IsError,
|
||||
|
||||
/// <summary>
|
||||
/// The robot's current order has been successfully completed.
|
||||
/// </summary>
|
||||
IsCompleted,
|
||||
|
||||
/// <summary>
|
||||
/// The robot is currently processing an order.
|
||||
/// </summary>
|
||||
IsProccessing,
|
||||
|
||||
/// <summary>
|
||||
/// The robot's current order has been canceled.
|
||||
/// </summary>
|
||||
IsCanceled,
|
||||
|
||||
/// <summary>
|
||||
/// The robot has no active order (order queue is empty).
|
||||
/// </summary>
|
||||
Empty
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace RobotNet10.FleetManager.Script;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the result of a robot operation, including success status and a descriptive message.
|
||||
/// </summary>
|
||||
/// <param name="IsSuccess">Indicates whether the operation completed successfully. <see langword="true"/> if successful; otherwise, <see langword="false"/>.</param>
|
||||
/// <param name="Message">A descriptive message providing details about the operation result. May contain error information if the operation failed.</param>
|
||||
public record RobotResult(bool IsSuccess, string Message);
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
using RobotNet.VDA5050.State;
|
||||
|
||||
namespace RobotNet10.FleetManager.Script;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the current state of a robot, including position, operational status, battery information, and load status.
|
||||
/// </summary>
|
||||
/// <param name="IsReady">Indicates whether the robot is ready to accept new commands. <see langword="true"/> if ready; otherwise, <see langword="false"/>.</param>
|
||||
/// <param name="Voltage">The current battery voltage in volts.</param>
|
||||
/// <param name="Loads">An array of loads currently carried by the robot. Empty array if no loads are present.</param>
|
||||
/// <param name="IsCharging">Indicates whether the robot is currently charging. <see langword="true"/> if charging; otherwise, <see langword="false"/>.</param>
|
||||
/// <param name="X">The X coordinate of the robot's current position in meters.</param>
|
||||
/// <param name="Y">The Y coordinate of the robot's current position in meters.</param>
|
||||
/// <param name="Theta">The orientation angle of the robot in radians. Range: [-Pi ... Pi].</param>
|
||||
public record RobotState(bool IsReady, double Voltage, Load[] Loads, bool IsCharging, double X, double Y, double Theta);
|
||||
Reference in New Issue
Block a user