/// <summary> /// This method will start the planning process and handle's the polling to the backend. When the planning is done or stopped/cancelled /// the async task will stop and return the <see cref="PlanningTask"/> object. /// </summary> /// <param name="request"></param> /// <param name="cancellationToken"></param> /// <param name="pollingInterval"></param> /// <returns></returns> public async Task <PlanningTask> Plan(PlanningRequest request, CancellationToken cancellationToken, TimeSpan?pollingInterval = null) { var pollingTimeSpan = pollingInterval ?? TimeSpan.FromSeconds(5); ClearAccessToken(); PlanningTask planningTask = null; try { planningTask = await api.PostPlanning(request, cancellationToken); PlanningTaskUpdated?.Invoke(this, new TaskPlanningUpdateEventArgs(planningTask)); do { await Task.Delay(pollingTimeSpan, cancellationToken); planningTask = await api.GetPlanning(planningTask.Id, cancellationToken); PlanningTaskUpdated?.Invoke(this, new TaskPlanningUpdateEventArgs(planningTask)); }while (planningTask.IsInProgress() && !cancellationToken.IsCancellationRequested); if (cancellationToken.IsCancellationRequested) { //Let's try to stop the planning task on the server as well. try { var task = api.StopPlanning(planningTask.Id, CancellationToken.None); await Task.WhenAny(task, Task.Delay(TimeSpan.FromSeconds(4))); } catch (Exception) { //Ignore this exception } planningTask.Status = PlanningTaskStatus.Canceled; PlanningTaskUpdated?.Invoke(this, new TaskPlanningUpdateEventArgs(planningTask)); } return(planningTask); } catch (ApiException e) { throw new Exception(e.Content); } catch (TaskCanceledException e) { if (planningTask == null) { planningTask = new PlanningTask(); } planningTask.Status = PlanningTaskStatus.Canceled; planningTask.Exception = e; PlanningTaskUpdated?.Invoke(this, new TaskPlanningUpdateEventArgs(planningTask)); return(planningTask); } }
public void Run() { _cancellationTokenSource = new CancellationTokenSource(); var cancellationToken = _cancellationTokenSource.Token; PlanningTask = Task.Run(() => { var res = PathPlanner.Run(Manipulator, Manipulator.Goal, InverseKinematicsSolver, cancellationToken); Manipulator.Path = res.Path; }, cancellationToken); ControlTask = PlanningTask.ContinueWith(task => { MotionController.Run(Manipulator, cancellationToken); }, cancellationToken); }
public static bool IsInProgress(this PlanningTask task) => task.Status switch {
public TaskPlanningUpdateEventArgs(PlanningTask planningTask) { this.PlanningTask = planningTask; }
static async Task Main(string[] args) { Console.WriteLine("--------------------------------------"); Console.WriteLine("| TaskPlanning.Client.Sample Console |"); Console.WriteLine("--------------------------------------"); Console.WriteLine(""); Console.WriteLine("0. Regular (plan until full)"); Console.WriteLine("1. Options (show all availible options for a single planitem)"); Console.WriteLine(""); Console.Write(">"); var key = Console.ReadKey(); Console.WriteLine(""); var mode = (PlanningMode)int.Parse(key.KeyChar.ToString()); //Create your client using your private access key var accessKey = string.Empty; if (File.Exists("AccessKey.txt")) { accessKey = File.ReadAllText("AccessKey.txt"); } TaskPlanningClient client; try { client = await TaskPlanningClient.Create(accessKey); client.PlanningTaskUpdated += Client_PlanningTaskUpdated; } catch (TaskPlanning.Client.InvalidAccessKeyException ex) { Console.WriteLine(ex.Message); return; } PlanningRequest request = GetPlanningRequest(mode); if (mode == PlanningMode.Options) { //When requesting options only one planitem is alowed. request.PendingPlanItems = new List <PlanItem> { request.PendingPlanItems.First() }; //In order to retrieve a list of possibilities in an existing planning you must provide //existing planned items per resource using the PrePlannedItems list var employee = request.Resources.First(); employee.PrePlannedItems.Add(new PlanItemResult { Item = new PlanItem { Duration = TimeSpan.FromHours(1), Location = HaarlemCity }, Window = new Window(new DateTime(2000, 1, 1, 9, 0, 0), TimeSpan.FromHours(1)) }); } PlanningTask planning = await client.Plan(request, TimeSpan.FromMilliseconds(500)); if (planning.Status == PlanningTaskStatus.Success) { if (mode == PlanningMode.Regular) { Console.WriteLine("Planned successfully:"); foreach (var planned in planning.Planning.PlannedItems) { Console.WriteLine($"{planned.Item.Id} on {planned.Window.Start}"); } Console.WriteLine(""); Console.WriteLine("Not planned:"); foreach (var notPlanned in planning.Planning.FailedToPlanItems) { Console.WriteLine($"{notPlanned.Item.Id} ({notPlanned.FailedReasonText})"); } } else if (mode == PlanningMode.Options) { Console.WriteLine($"Possible options for {planning.Planning.PlannedItems.FirstOrDefault()?.Item.Id}"); foreach (var planned in planning.Planning.PlannedItems) { Console.WriteLine($"{planned.Window.Start}"); } } } else { Console.WriteLine($"Whoops! something went wrong: {planning.Status}"); Console.WriteLine(planning.Exception.Message); } }