905 lines
29 KiB
C#
905 lines
29 KiB
C#
using AssetBundleBrowser.AssetBundleModel;
|
||
using BestHTTP;
|
||
using EasyInject.Attributes;
|
||
using Newtonsoft.Json;
|
||
using Newtonsoft.Json.Linq;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using Unity.VisualScripting;
|
||
using UnityEngine;
|
||
using UnityEngine.AI;
|
||
using UnityEngine.Playables;
|
||
using static UnityEditor.FilePathAttribute;
|
||
using UnityEngine.UIElements;
|
||
/// <summary>
|
||
/// 叉车AGV
|
||
/// </summary>
|
||
[GameObjectBean(ENameType.GameObjectName)]
|
||
public class ForkAgvDevice : AbstractDevice, ICar
|
||
{
|
||
[Autowired]
|
||
private AgvPopUI agvPopUI;
|
||
/// <summary>
|
||
/// 设备位置解析服务
|
||
/// </summary>
|
||
[Autowired("DeviceParseService")]
|
||
private readonly DeviceParseService deviceParseService;
|
||
/// <summary>
|
||
/// 提供网络服务
|
||
/// </summary>
|
||
[Autowired]
|
||
private readonly NetWorkComponent netWorkComponent;
|
||
/// <summary>
|
||
/// 车辆管理服务
|
||
/// </summary>
|
||
[Autowired]
|
||
private readonly AgvCarManage carManage;
|
||
|
||
[Autowired]
|
||
private ContainersManage containersManage;
|
||
/// <summary>
|
||
/// 路线高亮服务
|
||
/// </summary>
|
||
private LineRenderer lineRenderer;
|
||
|
||
[SerializeField]
|
||
private bool initialize = false;
|
||
|
||
[SerializeField]
|
||
private float _speed;
|
||
[Header("货叉")]
|
||
[SerializeField]
|
||
private GameObject forkCargo;
|
||
[Header("申请取货位置")]
|
||
[SerializeField]
|
||
private List<GameObject> applyTakePosition = new();
|
||
[Header("申请放货位置")]
|
||
[SerializeField]
|
||
private List<GameObject> applyPutPosition = new();
|
||
[Header("目标是设备角度设置")]
|
||
[SerializeField]
|
||
private List<ForkAgvRotationSet> forkAgvRotationSets = new();
|
||
[Header("目标是库位角度设置")]
|
||
[SerializeField]
|
||
public float shelfRotation = -90;
|
||
public string CarName => name;
|
||
[Header("可用巷道")]
|
||
public List<string> _allowRows = new List<string>();
|
||
[SerializeField]
|
||
private bool _hasTask;
|
||
[SerializeField]
|
||
private string _region;
|
||
[Header("路线颜色")]
|
||
[SerializeField]
|
||
private Color pathColor;
|
||
|
||
/// <summary>
|
||
/// 代理组件
|
||
/// </summary>
|
||
private NavMeshAgent agent;
|
||
|
||
/// <summary>
|
||
/// 时间轴组件
|
||
/// </summary>
|
||
private PlayableDirector playable;
|
||
|
||
/// <summary>
|
||
/// 当前agv任务
|
||
/// </summary>
|
||
[SerializeField]
|
||
private AgvTaskData taskData;
|
||
|
||
/// <summary>
|
||
/// 当前反馈状态
|
||
/// </summary>
|
||
[SerializeField]
|
||
private AgvCarManage.CarTaskStatusEnum currentFeedBackStatus;
|
||
|
||
private List<string> paths = new List<string>();
|
||
|
||
public bool hasTask => _hasTask;
|
||
|
||
public string Region => _region;
|
||
|
||
public List<string> AllowRows => _allowRows;
|
||
|
||
public override Transform Transform => transform;
|
||
|
||
public override string DeviceCode => name;
|
||
|
||
public override string DeviceType => "AGV";
|
||
|
||
public bool Initialize => initialize;
|
||
|
||
public bool HasGood{ get{ return forkCargo.GetComponentInChildren<Container>() != null;} }
|
||
|
||
float ICar.Speed { get => _speed; set { agent.speed = value; _speed = value; } }
|
||
|
||
public override DeviceData DeviceData => throw new NotImplementedException();
|
||
|
||
private AgvData _data = new();
|
||
private bool isOpenPop;
|
||
[Header("模拟反馈")]
|
||
[SerializeField]
|
||
private bool debugFeedBack;
|
||
//保存当前动画状态
|
||
public double animationTime;
|
||
public double animationSpeed;
|
||
public PlayState playState;
|
||
public Boolean agentIsStoping;
|
||
public Boolean agentRotationUpdate;
|
||
public Vector3 agentTarget;
|
||
|
||
[System.Serializable]
|
||
public class ForkAgvRotationSet
|
||
{
|
||
//设备
|
||
public List<GameObject> device;
|
||
//非库位取或放,agv保持的角度
|
||
public float deviceRotation;
|
||
}
|
||
|
||
private void Start()
|
||
{
|
||
agent = GetComponent<NavMeshAgent>();
|
||
agent.speed = _speed;
|
||
playable = GetComponent<PlayableDirector>();
|
||
playable.Pause();
|
||
lineRenderer = transform.GetOrAddComponent<LineRenderer>();
|
||
|
||
lineRenderer.positionCount = 0;
|
||
lineRenderer.startColor = pathColor;
|
||
lineRenderer.endColor = pathColor;
|
||
_data.deviecCode = name;
|
||
}
|
||
|
||
|
||
private void FixedUpdate()
|
||
{
|
||
//设备没初始化
|
||
if (!initialize)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (!hasTask)
|
||
{
|
||
return;
|
||
}
|
||
UpdateTask();
|
||
//当任务状态是下发状态是,执行
|
||
if (taskData.agvTaskStatus == AgvCarManage.CarTaskStatusEnum.SENT)
|
||
{
|
||
if (currentFeedBackStatus != AgvCarManage.CarTaskStatusEnum.TAKING)
|
||
{
|
||
currentFeedBackStatus = AgvCarManage.CarTaskStatusEnum.TAKING;
|
||
}
|
||
//多次申请
|
||
FeedBackTaskStatus(currentFeedBackStatus);
|
||
}
|
||
//取货中
|
||
if (taskData.agvTaskStatus == AgvCarManage.CarTaskStatusEnum.TAKING)
|
||
{
|
||
agent.isStopped = false;
|
||
//开始代理
|
||
StartAgent(taskData.fromLocation);
|
||
// 起点旋转位置
|
||
if (applyTakePosition.Count > 0)
|
||
{
|
||
Vector3 applyTakeVector = LastPosition(applyTakePosition,taskData.fromLocation);
|
||
//抵达后,申请取货流程
|
||
Vector3 targetPosition = new Vector3(applyTakeVector.x, transform.position.y, applyTakeVector.z);
|
||
if (Vector3.Distance(transform.position, targetPosition) <= 0.1f)
|
||
{
|
||
agent.isStopped = true;
|
||
agent.updateRotation = false;
|
||
currentFeedBackStatus = AgvCarManage.CarTaskStatusEnum.APPLY_TAKE;
|
||
FeedBackTaskStatus(currentFeedBackStatus);
|
||
}
|
||
}
|
||
}
|
||
//申请取货
|
||
if (taskData.agvTaskStatus == AgvCarManage.CarTaskStatusEnum.APPLY_TAKE)
|
||
{
|
||
//抵达终点
|
||
if (Vector3.Distance(transform.position, agent.destination) <= 0.1f)
|
||
{
|
||
//获取库位容器模型,绑定到货叉上
|
||
GameObject game = deviceParseService.GameObjectByDevice(taskData.fromLocation);
|
||
if (game != null)
|
||
{
|
||
Container container = game.GetComponentInChildren<Container>();
|
||
if (container != null)
|
||
{
|
||
container.transform.parent = forkCargo.transform;
|
||
playable.Play();
|
||
}
|
||
}
|
||
//反馈取货完成
|
||
currentFeedBackStatus = AgvCarManage.CarTaskStatusEnum.TAKE_FINISHED;
|
||
FeedBackTaskStatus(currentFeedBackStatus);
|
||
}
|
||
Quaternion targetRotation = RotationByDevice(taskData.fromDevice);
|
||
if (transform.localRotation == targetRotation)
|
||
{
|
||
//校验起点是设备,需要提升货叉到高位
|
||
if (!IsShelf(taskData.fromLocation))
|
||
{
|
||
if(playable.time <= 1.3)
|
||
{
|
||
playable.Play();
|
||
}
|
||
else
|
||
{
|
||
playable.Pause();
|
||
}
|
||
}
|
||
if(playable.state == PlayState.Paused)
|
||
{
|
||
agent.isStopped = false;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
transform.localRotation = Quaternion.RotateTowards(transform.localRotation, targetRotation, _speed * 2);
|
||
}
|
||
}
|
||
|
||
|
||
//取货完成
|
||
if (taskData.agvTaskStatus == AgvCarManage.CarTaskStatusEnum.TAKE_FINISHED)
|
||
{
|
||
if (HasGood)
|
||
{
|
||
//是库位取货方式
|
||
if (IsShelf(taskData.fromDevice))
|
||
{
|
||
if (playable.time >= 0.4)
|
||
{
|
||
OnMinFPS();
|
||
}
|
||
if (playable.state == PlayState.Paused)
|
||
{
|
||
agent.updateRotation = true;
|
||
currentFeedBackStatus = AgvCarManage.CarTaskStatusEnum.PUTTING;
|
||
FeedBackTaskStatus(currentFeedBackStatus);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//接驳点取货方式
|
||
//需要回退到指定位置做货叉下降动作
|
||
Vector3 target = LastPosition(applyTakePosition, taskData.fromDevice);
|
||
agent.isStopped = false;
|
||
//开始代理
|
||
StartAgent(target);
|
||
Vector3 targetPosition = new Vector3(target.x, transform.position.y, target.z);
|
||
//到位后,开始下降货叉
|
||
if (Vector3.Distance(transform.position, targetPosition) <= 0.1f)
|
||
{
|
||
if (playable.time >= 0.4)
|
||
{
|
||
playable.playableGraph.GetRootPlayable(0).SetSpeed(-1);
|
||
playable.Play();
|
||
}
|
||
else
|
||
{
|
||
playable.Pause();
|
||
agent.updateRotation = true;
|
||
currentFeedBackStatus = AgvCarManage.CarTaskStatusEnum.PUTTING;
|
||
FeedBackTaskStatus(currentFeedBackStatus);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//货叉升到满叉才执行后续动作
|
||
if (playable.time < 1.99)
|
||
{
|
||
playable.Play();
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
GameObject game = deviceParseService.GameObjectByDevice(taskData.fromLocation);
|
||
if (game != null)
|
||
{
|
||
Container container = game.GetComponentInChildren<Container>();
|
||
|
||
if (container != null)
|
||
{
|
||
container.Agent.enabled = false;
|
||
container.transform.parent = forkCargo.transform;
|
||
playable.Play();
|
||
}
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
//放货中
|
||
if (taskData.agvTaskStatus == AgvCarManage.CarTaskStatusEnum.PUTTING)
|
||
{
|
||
//未代理开始代理
|
||
StartAgent(taskData.toLocation);
|
||
|
||
// 起点旋转位置
|
||
if (applyPutPosition.Count > 0)
|
||
{
|
||
Vector3 applyPutVector = LastPosition(applyPutPosition, taskData.toLocation);
|
||
//抵达后,申请取货流程
|
||
Vector3 targetPosition = new Vector3(applyPutVector.x, transform.position.y, applyPutVector.z);
|
||
if (Vector3.Distance(transform.position, targetPosition) <= 0.1f)
|
||
{
|
||
agent.isStopped = true;
|
||
agent.updateRotation = false;
|
||
currentFeedBackStatus = AgvCarManage.CarTaskStatusEnum.APPLY_PUT;
|
||
FeedBackTaskStatus(currentFeedBackStatus);
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
//申请放货
|
||
if (taskData.agvTaskStatus == AgvCarManage.CarTaskStatusEnum.APPLY_PUT && currentFeedBackStatus == AgvCarManage.CarTaskStatusEnum.APPLY_PUT)
|
||
{
|
||
//抵达终点
|
||
if (Vector3.Distance(transform.position, agent.destination) <= 0.1f)
|
||
{
|
||
currentFeedBackStatus = AgvCarManage.CarTaskStatusEnum.PUT_FINISHED;
|
||
|
||
}
|
||
Quaternion targetRotation = RotationByDevice(taskData.toDevice);
|
||
if (transform.localRotation == targetRotation)
|
||
{
|
||
//启用代理
|
||
agent.isStopped = false;
|
||
//如果是设备将货叉提升完
|
||
if(!IsShelf(taskData.toLocation))
|
||
{
|
||
playable.Play();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
transform.localRotation = Quaternion.RotateTowards(transform.localRotation, targetRotation, _speed * 2);
|
||
}
|
||
}
|
||
|
||
if (currentFeedBackStatus == AgvCarManage.CarTaskStatusEnum.PUT_FINISHED)
|
||
{
|
||
if (HasGood)
|
||
{
|
||
//校验是库位还是设备
|
||
|
||
if(IsShelf(taskData.toLocation))
|
||
{
|
||
Debug.LogWarning("放货持续");
|
||
if (playable.time > 0)
|
||
{
|
||
playable.playableGraph.GetRootPlayable(0).SetSpeed(-1);
|
||
playable.Play();
|
||
}
|
||
else
|
||
{
|
||
//暂停播放
|
||
//playable.Pause();
|
||
////解绑容器
|
||
//Container container = forkCargo.transform.GetComponentInChildren<Container>();
|
||
//container.transform.parent = null;
|
||
OnMaxFPS();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (playable.time > 1.5f)
|
||
{
|
||
playable.playableGraph.GetRootPlayable(0).SetSpeed(-1);
|
||
playable.Play();
|
||
}
|
||
else
|
||
{
|
||
OnMaxFPS();
|
||
}
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
if(!IsShelf(taskData.toLocation))
|
||
{
|
||
//当后退完成后最终下降完货叉,并重置agv状态
|
||
Vector3 position = LastPosition(applyPutPosition, taskData.toLocation);
|
||
Vector3 targetPosition = new Vector3(position.x, transform.position.y, position.z);
|
||
|
||
if (Vector3.Distance(transform.position, targetPosition) <= 0.1f)
|
||
{
|
||
if(playable.time > 0)
|
||
{
|
||
playable.Play();
|
||
}
|
||
else
|
||
{
|
||
playable.Pause();
|
||
FeedBackTaskStatus(currentFeedBackStatus);
|
||
Rest();
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Vector3 position = LastPosition(applyPutPosition, taskData.toLocation);
|
||
Vector3 targetPosition = new Vector3(position.x, transform.position.y, position.z);
|
||
if (Vector3.Distance(transform.position, targetPosition) <= 0.1f)
|
||
{
|
||
GameObject game = deviceParseService.GameObjectByDevice(taskData.toLocation);
|
||
Container container = containersManage.GetContainerByCode(taskData.containerCode);
|
||
container.transform.parent = game.transform;
|
||
container.transform.localPosition = new Vector3(0, -0.2472343f, 0.0006999969f);
|
||
container.Agent.enabled = true;
|
||
FeedBackTaskStatus(currentFeedBackStatus);
|
||
Rest();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 重置设备状态
|
||
/// </summary>
|
||
public void Rest()
|
||
{
|
||
taskData = new AgvTaskData();
|
||
_hasTask = false;
|
||
paths.Clear();
|
||
currentFeedBackStatus =AgvCarManage.CarTaskStatusEnum.STANDBY;
|
||
agent.ResetPath();
|
||
agent.isStopped = false;
|
||
agent.updateRotation = true;
|
||
playable.playableGraph.GetRootPlayable(0).SetSpeed(1);
|
||
playable.time = 0;
|
||
playable.Pause();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 反馈任务状态
|
||
/// </summary>
|
||
public void FeedBackTaskStatus(AgvCarManage.CarTaskStatusEnum status,string feedBacklocation = "")
|
||
{
|
||
if(debugFeedBack)
|
||
{
|
||
taskData.agvTaskStatus = status;
|
||
}
|
||
FeedBackEntity feedBackDTO = new FeedBackEntity();
|
||
feedBackDTO.feedbackStatus = status.ToString();
|
||
feedBackDTO.feedbackLocation = feedBacklocation;
|
||
feedBackDTO.taskCode = taskData.instructionCode;
|
||
feedBackDTO.carId = taskData.carId;
|
||
netWorkComponent.RemoteFeedBackAgvTaskStatus(feedBackDTO, OnFeedBack);
|
||
}
|
||
/// <summary>
|
||
/// 接受反馈回调信息
|
||
/// </summary>
|
||
private void OnFeedBack(HTTPRequest originalRequest, HTTPResponse response)
|
||
{
|
||
if(response == null)
|
||
{
|
||
return;
|
||
}
|
||
//请求成功
|
||
if (response.IsSuccess)
|
||
{
|
||
try
|
||
{
|
||
//解析反馈
|
||
JObject result = JObject.Parse(response.DataAsText);
|
||
bool isSuccesss = bool.Parse(result["success"].ToString());
|
||
//后台处理反馈成功
|
||
if (isSuccesss)
|
||
{
|
||
//更新当前任务状态,懒更新
|
||
// taskData.agvTaskStatus = currentFeedBackStatus;
|
||
//agent.isStopped = true;
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError(name + " 反馈 =" + response.DataAsText);
|
||
}
|
||
}
|
||
catch(Exception ex)
|
||
{
|
||
|
||
}
|
||
|
||
|
||
|
||
}
|
||
}
|
||
private void Reset()
|
||
{
|
||
taskData = null;
|
||
_hasTask = false;
|
||
agent.ResetPath();
|
||
}
|
||
public void SendTask(AgvTaskData taskData)
|
||
{
|
||
//if (!Initialize)
|
||
//{
|
||
// return;
|
||
//}
|
||
this.taskData = taskData;
|
||
_hasTask = true;
|
||
}
|
||
/// <summary>
|
||
/// 检查数据并初始化
|
||
/// </summary>
|
||
private void CheckValueAndInit(HTTPRequest originalRequest, HTTPResponse response)
|
||
{
|
||
|
||
//响应成功
|
||
if (response.IsSuccess)
|
||
{
|
||
try
|
||
{
|
||
JObject result = JObject.Parse(response.DataAsText);
|
||
|
||
if (result["object"] == null)
|
||
{
|
||
Debug.LogWarning("检查数据并初始化" + $"{response.DataAsText}");
|
||
return;
|
||
}
|
||
string json = result["object"].ToString();
|
||
CarStatusEntity statusEntity = JsonConvert.DeserializeObject<CarStatusEntity>(json);
|
||
if (statusEntity != null && statusEntity.task != null)
|
||
{
|
||
//任务存在的时候才运行初始位置
|
||
if (carManage.Contains(statusEntity.task))
|
||
{
|
||
|
||
}
|
||
Debug.LogWarning(name + "agv 初始化赋值 =" + JsonConvert.SerializeObject(statusEntity.task));
|
||
//agv本体
|
||
this.SendTask(statusEntity.task);
|
||
this.transform.localPosition = statusEntity.posistion.ToVector();
|
||
this.transform.localRotation = statusEntity.roation.ToQuaternion();
|
||
this.transform.localScale = statusEntity.scale.ToVector();
|
||
this.currentFeedBackStatus = statusEntity.currentFeedBackStatus;
|
||
|
||
//货叉
|
||
if (statusEntity.cargoStatus != null)
|
||
{
|
||
//forkCargo.transform.localPosition = statusEntity.cargoStatus.posistion.ToVector();
|
||
//forkCargo.transform.localRotation = statusEntity.cargoStatus.roation.ToQuaternion();
|
||
//forkCargo.transform.localScale = statusEntity.cargoStatus.scale.ToVector();
|
||
playable.time = statusEntity.cargoStatus.animationTime;
|
||
if (statusEntity.cargoStatus.playState == PlayState.Playing)
|
||
{
|
||
playable.Play();
|
||
}
|
||
if (statusEntity.cargoStatus.playState == PlayState.Paused)
|
||
{
|
||
playable.Pause();
|
||
}
|
||
playable.RebuildGraph();
|
||
playable.playableGraph.GetRootPlayable(0).SetSpeed(statusEntity.cargoStatus.animationSpeed);
|
||
}
|
||
//容器
|
||
if (statusEntity.containerStatus != null)
|
||
{
|
||
Container container = ApplicationBoot.Instance.GetBean<Container>(statusEntity.containerStatus.deviceCode);
|
||
container.transform.localPosition = statusEntity.containerStatus.posistion.ToVector();
|
||
container.transform.localRotation = statusEntity.containerStatus.roation.ToQuaternion();
|
||
container.transform.localScale = statusEntity.containerStatus.scale.ToVector();
|
||
container.transform.parent = forkCargo.transform;
|
||
}
|
||
initialize = true;
|
||
}
|
||
}catch(Exception x) { }
|
||
|
||
}
|
||
else
|
||
{
|
||
// Debug.LogWarning(name + ":获取缓存数据响应=" + response.DataAsText);
|
||
// Debug.LogWarning(string.Format("【url:{0}】", originalRequest.CurrentUri));
|
||
|
||
}
|
||
initialize = true;
|
||
}
|
||
|
||
private void OnDestroy()
|
||
{
|
||
Shutdown();
|
||
}
|
||
public void Shutdown()
|
||
{
|
||
//当前agv的设备信息
|
||
CarStatusEntity carStatus = new();
|
||
carStatus.scale = Utils.ToSerializationVectorByVector(transform.localScale);
|
||
carStatus.posistion = Utils.ToSerializationVectorByVector(transform.localPosition);
|
||
carStatus.roation = Utils.ToSerializationVectorByVector(transform.localRotation.eulerAngles);
|
||
carStatus.deviceCode = DeviceCode;
|
||
carStatus.modelId = GetInstanceID();
|
||
carStatus.currentFeedBackStatus = currentFeedBackStatus;
|
||
carStatus.agentIsStoping = this.agentIsStoping;
|
||
carStatus.agentRotationUpdate = this.agentRotationUpdate;
|
||
carStatus.target = Utils.ToSerializationVectorByVector(this.agentTarget);
|
||
//货叉设备信息
|
||
CarStatusEntity cargo = new()
|
||
{
|
||
scale = Utils.ToSerializationVectorByVector(forkCargo.transform.localScale),
|
||
posistion = Utils.ToSerializationVectorByVector(forkCargo.transform.localPosition),
|
||
roation = Utils.ToSerializationVectorByVector(forkCargo.transform.localRotation.eulerAngles),
|
||
modelId = forkCargo.GetInstanceID(),
|
||
deviceCode = forkCargo.name,
|
||
animationTime = animationTime,
|
||
animationSpeed = animationSpeed,
|
||
playState = this.playState
|
||
};
|
||
//有货
|
||
if (HasGood)
|
||
{
|
||
CarStatusEntity containerStatus = new();
|
||
Container container = forkCargo.GetComponentInChildren<Container>();
|
||
containerStatus.scale = Utils.ToSerializationVectorByVector(container.transform.localScale);
|
||
containerStatus.posistion = Utils.ToSerializationVectorByVector(container.transform.localPosition);
|
||
containerStatus.roation = Utils.ToSerializationVectorByVector(container.transform.localRotation.eulerAngles);
|
||
|
||
carStatus.containerStatus = containerStatus;
|
||
}
|
||
carStatus.cargoStatus = cargo;
|
||
if(taskData != null && taskData.instructionId != 0)
|
||
{
|
||
carStatus.task = taskData;
|
||
}
|
||
|
||
//保存当前设备数据
|
||
netWorkComponent.RemoteSaveData(name, carStatus, SaveResult);
|
||
}
|
||
|
||
private void SaveResult(HTTPRequest originalRequest, HTTPResponse response)
|
||
{
|
||
if (response == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
if (response.IsSuccess)
|
||
{
|
||
Debug.Log("保存返回= " + response.DataAsText);
|
||
}
|
||
else
|
||
{
|
||
Debug.Log("保存返回= " + response.DataAsText);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 开始代理
|
||
/// </summary>
|
||
/// <param name="deviceName"></param>
|
||
public void StartAgent(string deviceName)
|
||
{
|
||
//未代理开始代理
|
||
if (!paths.Contains(deviceName))
|
||
{
|
||
Vector3 targetPosistion = deviceParseService.PositionByDevice(deviceName);
|
||
agent.SetDestination(targetPosistion);
|
||
lineRenderer.positionCount = 0;
|
||
lineRenderer.SetPositions(agent.path.corners);
|
||
paths.Add(taskData.fromLocation);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 开始代理
|
||
/// </summary>
|
||
/// <param name="deviceName"></param>
|
||
public void StartAgent(Vector3 target)
|
||
{
|
||
agent.SetDestination(target);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 取货完成
|
||
/// </summary>
|
||
public void OnTakeFinish()
|
||
{
|
||
currentFeedBackStatus = AgvCarManage.CarTaskStatusEnum.TAKE_FINISHED;
|
||
|
||
}
|
||
public void MouseLeftDown()
|
||
{
|
||
CameraFollow cameraFollow = transform.GetComponent<CameraFollow>();
|
||
if (cameraFollow)
|
||
{
|
||
cameraFollow.OnEnter();
|
||
}
|
||
|
||
}
|
||
/// <summary>
|
||
/// 更新任务
|
||
/// </summary>
|
||
public void UpdateTask()
|
||
{
|
||
|
||
_data.feedBack = currentFeedBackStatus.ToString();
|
||
if(taskData != null)
|
||
{
|
||
AgvTaskData task = carManage.GetTaskByCode(taskData.instructionCode);
|
||
try
|
||
{
|
||
animationSpeed = playable.playableGraph.GetRootPlayable(0).GetSpeed();
|
||
|
||
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
|
||
}
|
||
animationTime = playable.time;
|
||
playState = playable.state;
|
||
agentIsStoping = agent.isStopped;
|
||
agentRotationUpdate = agent.updateRotation;
|
||
agentTarget = agent.destination;
|
||
if (task != null)
|
||
{
|
||
taskData = task;
|
||
_data.container = taskData.containerCode;
|
||
_data.startDevice = taskData.fromLocation;
|
||
_data.endDevice = taskData.toLocation;
|
||
_data.currentAction = taskData.agvTaskStatus.ToString();
|
||
}
|
||
else
|
||
{
|
||
Rest();
|
||
}
|
||
}
|
||
|
||
}
|
||
public void OnInit()
|
||
{
|
||
//获取远程缓存
|
||
netWorkComponent.RemoteGetDataByLable(name, CheckValueAndInit);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 任务状态反馈实体
|
||
/// </summary>
|
||
private class FeedBackEntity
|
||
{
|
||
public string systemCode = "DT";
|
||
public string houseCode = "DT";
|
||
public long taskCode;
|
||
public string carId;
|
||
public string taskType;
|
||
public string feedbackStatus;
|
||
public string feedbackLocation;
|
||
}
|
||
/// <summary>
|
||
/// 车辆状态实体
|
||
/// </summary>
|
||
[System.Serializable]
|
||
private class CarStatusEntity : DeviceStatus
|
||
{
|
||
public AgvTaskData task;
|
||
public AgvCarManage.CarTaskStatusEnum currentFeedBackStatus;
|
||
public Boolean agentIsStoping;
|
||
public Boolean agentRotationUpdate;
|
||
public SerializationVector target;
|
||
public DeviceStatus cargoStatus;
|
||
public DeviceStatus containerStatus;
|
||
}
|
||
/// <summary>
|
||
/// 解析申请取放货坐标
|
||
/// </summary>
|
||
/// <param name="objects"></param>
|
||
/// <param name="name"></param>
|
||
/// <returns></returns>
|
||
/// <exception cref="Exception"></exception>
|
||
public Vector3 LastPosition(List<GameObject> objects, string name)
|
||
{
|
||
//如果的库位
|
||
if (name.Contains("-"))
|
||
{
|
||
string[] str = name.Split('-');
|
||
GameObject game = objects.Find(v => string.Equals(v.name, "row_" + str[0]));
|
||
if (game != null)
|
||
{
|
||
return new Vector3(game.transform.position.x, transform.position.y, game.transform.position.z);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//设备
|
||
GameObject game = objects.Find(v => string.Equals(v.name, "device_" +name));
|
||
if (game != null)
|
||
{
|
||
return new Vector3(game.transform.position.x,transform.position.y,game.transform.position.z);
|
||
}
|
||
}
|
||
throw new Exception(string.Format("【{0}】未配置申请取放货坐标【{1}】",this.name,name));
|
||
}
|
||
|
||
|
||
private Quaternion RotationByDevice(string name)
|
||
{
|
||
if(name.Contains("shelf"))
|
||
{
|
||
return Quaternion.Euler(0,shelfRotation , 0);
|
||
}
|
||
else
|
||
{
|
||
foreach (var itme in forkAgvRotationSets)
|
||
{
|
||
GameObject obj = itme.device.Find(v => string.Equals(v.name, name));
|
||
|
||
if (obj != null)
|
||
{
|
||
return Quaternion.Euler(0, itme.deviceRotation, 0);
|
||
}
|
||
}
|
||
}
|
||
throw new Exception(string.Format("未找到该设备【{0}】旋转角度",name));
|
||
}
|
||
/// <summary>
|
||
/// 在动画指定最小帧时触发
|
||
/// </summary>
|
||
public void OnMinFPS()
|
||
{
|
||
//有货停止播放
|
||
if (HasGood)
|
||
{
|
||
playable.Pause();
|
||
}
|
||
}
|
||
public void OnMaxFPS()
|
||
{
|
||
|
||
if (currentFeedBackStatus == AgvCarManage.CarTaskStatusEnum.PUT_FINISHED)
|
||
{
|
||
|
||
//暂停播放
|
||
playable.Pause();
|
||
//解绑容器
|
||
Container container = forkCargo.transform.GetComponentInChildren<Container>();
|
||
container.transform.parent = null;
|
||
container.Agent.enabled = true;
|
||
//agv得退出一段距离
|
||
//倒退位置坐标
|
||
Vector3 applyPutVector = LastPosition(applyPutPosition, taskData.toLocation);
|
||
//开始代理
|
||
StartAgent(applyPutVector);
|
||
|
||
}
|
||
|
||
}
|
||
/// <summary>
|
||
/// 校验当前目标是否是库位
|
||
/// </summary>
|
||
/// <param name="name"></param>
|
||
public bool IsShelf(string name)
|
||
{
|
||
return name.Contains("-") || name.Contains("shelf");
|
||
}
|
||
|
||
public override void DataHandle(object data, object other = null)
|
||
{
|
||
|
||
}
|
||
|
||
public override void ProcessCompleted()
|
||
{
|
||
}
|
||
|
||
public override T DynamicData<T>()
|
||
{
|
||
return (T)(object) _data;
|
||
}
|
||
public override void MouseSingleClick()
|
||
{
|
||
base.MouseSingleClick();
|
||
isOpenPop = !isOpenPop;
|
||
agvPopUI.Open(this, isOpenPop);
|
||
}
|
||
}
|