Files

177 lines
7.0 KiB
C#

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;
}
}