using SimpleCore.BasicProps; using SimpleCore.Library; using SimpleCore.Traffic; using SimpleCore; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CommonUsage.Protocols.VDA5050.Objects; using System.Security.Cryptography.X509Certificates; using System.Numerics; using System.Threading; using System.Net; using System.Net.Http; using Nancy.Routing; using Newtonsoft.Json; using Simple3; namespace StandardScene.CarTypes { internal class VDA5050Interface : AGVInterface { public static int TaskId = 0; HttpClient hc = new HttpClient(); public override bool TryLock(int siteId) { if (!_car.status.usage.Get().scheduling) throw new Exception("abandoned"); var siteId_temp = siteId; var pendinglocks0 = _car.status.pendingLocks[0]; if (siteId_temp != pendinglocks0) { throw new Exception("lock not according to sequence"); } return TrafficControl.TryLock(_car, siteId); } public override void Leave(int siteId) { TrafficControl.Leave(_car, siteId); } public VDA5050Interface(int id) { _car = (VDA5050Car)SimpleLib.GetCar(id); // _car.RouteCache = new(); // _car.TaskId = TaskId++; if (_car.RouteCache.Count ==0||_car.RouteCache.Count>0&&_car.RouteCache.Last().State==VDA5050Segment.SegState.Executed)//接续任务 { // _car.RouteCache = new(); // _car.ResetLastNodeSequenceId(); _car.ReseData(); _car.TaskId = TaskId; TaskId += 1; } } public void Go(int srcId, int dstId, int trackId, int speed = -1, bool reverse = false, float[] trackTypeInfo = null) { VDA5050Segment src, dst, track; lock (_car.RouteCache) { //Console.WriteLine("_car.RouteCache.Count: " + _car.RouteCache.Count); if (_car.RouteCache.Count == 0) { src = new(new node() { nodeId = VDA5050Helper.GetVDA5050Id(srcId), nodePosition = new() { x = SimpleLib.GetSite(srcId).x, y = SimpleLib.GetSite(srcId).y } }, VDA5050Segment.SegState.Waiting); _car.RouteCache.Add(src); } else src = _car.RouteCache.Last(); if (trackTypeInfo.Length != 0 && trackTypeInfo[0] == 3) { var controlPointNum = (int)trackTypeInfo[1]; var controlPoints = new controlPoint[controlPointNum]; for (int pt = 2; pt < controlPointNum * 2 + 2; pt += 2) { controlPoints[pt/2-1] = new controlPoint(trackTypeInfo[pt], trackTypeInfo[pt + 1], trackTypeInfo[1 + controlPointNum * 2 + pt / 2]); } var knotVector = new float[controlPointNum*2]; for (int i = 0; i < controlPointNum; i++) { knotVector[i] = 0f; knotVector[i + controlPointNum] = 1f; } var trajectory = new trajectory(){controlPoints = controlPoints,degree = controlPointNum,knotVector = knotVector }; track = new(new edge() { edgeId = VDA5050Helper.GetVDA5050Id(trackId), startNodeId = VDA5050Helper.GetVDA5050Id(srcId), endNodeId = VDA5050Helper.GetVDA5050Id(dstId), trajectory = trajectory, orientation = reverse ? Math.PI : 0.0, action = [new action() { actionDescription = $"{VDA5050Helper.GetVDA5050Id(trackId)}", actionId = Guid.NewGuid().ToString() }] }, VDA5050Segment.SegState.Waiting); } else { track = new(new edge() { edgeId = VDA5050Helper.GetVDA5050Id(trackId), startNodeId = VDA5050Helper.GetVDA5050Id(srcId), endNodeId = VDA5050Helper.GetVDA5050Id(dstId), trackTypeInfo = trackTypeInfo, orientation = reverse ? Math.PI : 0.0, action = [new action() { actionDescription = $"{VDA5050Helper.GetVDA5050Id(trackId)}", actionId = Guid.NewGuid().ToString() }] }, VDA5050Segment.SegState.Waiting); } dst = new(new node() { nodeId = VDA5050Helper.GetVDA5050Id(dstId), nodePosition = new() { x = SimpleLib.GetSite(dstId).x, y = SimpleLib.GetSite(dstId).y }, actions = [new action() { actionDescription = $"{VDA5050Helper.GetVDA5050Id(dstId)}", actionId = Guid.NewGuid().ToString() }] }, VDA5050Segment.SegState.Waiting); _car.RouteCache.Add(track); _car.RouteCache.Add(dst); } Queue(async () => { while (!TryLock(dstId)) await Task.Delay(10); lock (_car.RouteCache) { if (src.Item.sequenceId == 0) { src.State = VDA5050Segment.SegState.BaseSending; } track.State = VDA5050Segment.SegState.BaseSending; dst.State = VDA5050Segment.SegState.BaseSending; src.Item.released = true; track.Item.released = true; dst.Item.released = true; } }, async () => { await src.FinishToken.Task; Leave(srcId); }); } public void ChangeDI41Signal() { hc.GetStringAsync($"http://{_car.address}:8008/setValue?FieldName=DI41&Value=True"); Diagnosis.Log("将DI41置为True", "VDA5050", true); Thread.Sleep(1000); hc.GetStringAsync($"http://{_car.address}:8008/setValue?FieldName=DI41&Value=False"); Diagnosis.Log("1秒后将DI41置为False", "VDA5050", true); } public void Sleep(int SleepTime) { Diagnosis.Log("小车开始Sleep" + SleepTime + "ms", "VDA5050", true); Thread.Sleep(SleepTime); Diagnosis.Log("小车结束Sleep", "VDA5050", true); } public void WaitAO3Signal() { while(_car.AO3 == 0) { Thread.Sleep(200); } Diagnosis.Log($"AO3: " + _car.AO3, "VDA5050", true); Diagnosis.Log("获取到AO3信号为1,继续下个任务", "VDA5050", true); } private VDA5050Car _car; } }