add - 手动控制可用

master
SoulStar 3 months ago
parent d3e8571819
commit 126faa114d

@ -117,7 +117,7 @@ namespace SlnMesnac.Business.@base
{
return false;
}
if(agvState.agvworkstate == "忙碌" || agvState.agvalarmstate == "正常")
if(agvState.agvworkstate != "待机")
{
var response = _airPorthttpClient.AGVOperationalTaskRequest(new AGVRequestOperationalTaskEntity()
{
@ -138,7 +138,7 @@ namespace SlnMesnac.Business.@base
return false;
}
}
else if(agvState.agvworkstate == "空闲")
else if(agvState.agvworkstate == "待机")
{
_logger.LogError($"AGV {agvState.agvno} 现在无任务");
return false;
@ -204,5 +204,21 @@ namespace SlnMesnac.Business.@base
return _AGVMapPointService.DeleteAndAddAgvMapPoint(list);
}
public static string AGVTaskStatusSelect(int no)
{
switch (no)
{
case 0: return "已终止";
case 1: return "待执行";
case 2: return "正在执行";
case 3: return "已完成";
case 4: return "已取消";
case 5: return "已暂停";
case 6: return "匹配中";
case 7: return "核验中";
default: return "未知代码";
}
}
}
}

@ -25,7 +25,7 @@ namespace SlnMesnac.Business.@base
_AGVStateService = agvService;
_airPorthttpClient = airPorthttpClient;
_aGVSettingService = aGVSettingService;
updateTimer = new System.Timers.Timer(2000);
updateTimer = new System.Timers.Timer(1000);
updateTimer.Elapsed += async (sender, e) => await TimerUpadteAGVState();
}
@ -71,9 +71,7 @@ namespace SlnMesnac.Business.@base
public async Task TimerUpadteAGVState()
{
bool result;
result = await UpdateALLAGVStateByResposne();
if (!result)
if (!await UpdateALLAGVStateByResposne())
{
_logger.LogError("AGV状态更新失败");
}
@ -101,7 +99,7 @@ namespace SlnMesnac.Business.@base
agvno = entity.Guid,
agvalarmstate = entity.AgvMoveStatus != 6 ? "正常" : "异常",
agvtype = _aGVSettingService.GetAgvSettingByID(entity.Guid),
agvworkstate = entity.AgvMoveStatus == 1 ? "空闲" : "忙碌",
agvworkstate = AGVStatusSelect(entity.AgvMoveStatus),
refreshtime = DateTime.Now,
taskno = entity.TaskID,
};
@ -115,6 +113,31 @@ namespace SlnMesnac.Business.@base
return false;
}
}
/// <summary>
/// AGV运动状态对照
/// </summary>
/// <param name="no"></param>
/// <returns></returns>
public static string AGVStatusSelect(int no)
{
switch (no)
{
case 0: return "暂无信息";
case 1: return "待机";
case 2: return "执行任务";
case 3: return "充电中";
case 4: return "暂停";
case 5: return "急停";
case 6: return "异常";
case 7: return "建图中";
case 8: return "等待";
case 9: return "调度控制";
case 51: return "同步";
case 52: return "脱机";
default: return "未知代码";
}
}
}
public enum TimerControl

@ -105,7 +105,7 @@ namespace SlnMesnac.Business.@base
{
//获取任务列表
List<AirportTask> Task = _Taskservice.GetAGVTaskInfos();
if (Task != null || Task.Count > 0)
if (Task != null && Task.Count > 0)
{
//更新前端
_RefreshLogMessageAction?.Invoke("任务数量:" + Task.Count);

@ -15,7 +15,6 @@ namespace SlnMesnac.Business.@base
{
private ILogger<VisionBusiness> _logger;
private static VisionBusiness instance;
private TcpServer _tcpServer;
public VisionBusiness(ILogger<VisionBusiness> logger, TcpServer tcpServer)
@ -58,6 +57,8 @@ namespace SlnMesnac.Business.@base
public void RequestVisionReplace(string port)
{
_tcpServer.SendStackOverRequestVisionSysReplace(port);
VDCount = 1;
VACount = 1;
}
/// <summary>
@ -101,8 +102,9 @@ namespace SlnMesnac.Business.@base
}
}
int VCount = 1;
int VDCount = 1;
int VACount = 0;
bool Vjudge = true;
/// <summary>
/// 接受码垛结果
/// </summary>
@ -115,29 +117,38 @@ namespace SlnMesnac.Business.@base
_logger.LogInformation($"视觉系统一次码垛结束,码垛完成");
//上位机回复收到码垛结果
_tcpServer.SendReplayStackResult(id);
if (VCount < 5) //这里写是否继续下一次码垛的判断条件
if ((VDCount < 4 && Vjudge == true) || (VACount < 3 && Vjudge == false)) //这里写是否继续下一次码垛的判断条件
{
//如果码垛没结束继续发下一次的码垛信号
if (true) //这里写向哪个机器人码垛的判断条件
if (Vjudge) //这里写向哪个机器人码垛的判断条件
{
//发送向搬运机器人AGVDeliver码垛的信号
RequestVisionStartWork(StackState.AGVNoPositioning, id);
_logger.LogInformation("下一次码垛开始,方向:搬运机器人");
VDCount++;
if (VDCount >= 4)
{
Vjudge = false;
}
}
else
{
//发送向复合机器人AMR码垛的信号
RequestVisionStartWork(StackState.AMRNoPositioning, id);
_logger.LogInformation("下一次码垛开始,方向:复合机器人");
VACount++;
if (VACount >= 3)
{
Vjudge = true;
}
}
VCount++;
}
else
{
//如果码垛结束就请求复位
RequestVisionReplace(id);
_logger.LogInformation("本次码垛结束,请求复位");
VCount = 1;
}
}
else if (entity.DataBytes[0] == 0x01)

@ -9,5 +9,7 @@ namespace SlnMesnac.Config
public string AGVGUID { get; set; }
public string AGVName { get; set; }
public string AGVIp { get; set; }
}
}

@ -50,7 +50,7 @@ namespace SlnMesnac.Model.AirportApiEntity
/// <summary>
/// 错误
/// </summary>
public List<AGVErrorEntity> error { get; set; }
public List<AGVErrorEntity>? error { get; set; }
}

@ -51,8 +51,9 @@ namespace SlnMesnac.Repository.service.Impl
List<AirportTask> taskInfos = null;
try
{
string sql = "SELECT id,ConveyorNo,TaskNo,FlightNo,DeliverAGVNo, MAX(StartTime) as StartTime,TaskState, TotalCount ,LoadCount FROM AirportTask group by ConveyorNo ";
taskInfos = base._rep.AsTenant().GetConnection("AGV").Ado.SqlQuery<AirportTask>(sql);
//string sql = "SELECT id,ConveyorNo,TaskNo,FlightNo,DeliverAGVNo, MAX(StartTime) as StartTime,TaskState, TotalCount ,LoadCount FROM AirportTask group by ConveyorNo ";
//taskInfos = base._rep.AsTenant().GetConnection("AGV").Ado.SqlQuery<AirportTask>(sql);
taskInfos = _rep.GetList();
}
catch (Exception ex)
{
@ -70,8 +71,9 @@ namespace SlnMesnac.Repository.service.Impl
List<AirportTask> taskInfos = null;
try
{
string sql = "select *from ( SELECT id, ConveyorNo,TaskNo,FlightNo,DeliverAGVNo, amragvno,MAX(StartTime) as StartTime,TaskState, TotalCount ,LoadCount FROM AirportTask group by ConveyorNo )";
taskInfos = base._rep.AsTenant().GetConnection("AGV").Ado.SqlQuery<AirportTask>(sql);
//string sql = "select *from ( SELECT id, ConveyorNo,TaskNo,FlightNo,DeliverAGVNo, amragvno,MAX(StartTime) as StartTime,TaskState, TotalCount ,LoadCount FROM AirportTask group by ConveyorNo )";
//taskInfos = base._rep.AsTenant().GetConnection("AGV").Ado.SqlQuery<AirportTask>(sql);
taskInfos = _rep.GetList();
}
catch (Exception ex)
{

@ -20,6 +20,9 @@ using Serilog.Events;
using Microsoft.Extensions.Logging;
using System.Net.Http;
using static System.Net.WebRequestMethods;
using TouchSocket.Http;
using HttpClient = System.Net.Http.HttpClient;
using HttpMethod = System.Net.Http.HttpMethod;
namespace SlnMesnac.TouchSocket
{
@ -27,6 +30,8 @@ namespace SlnMesnac.TouchSocket
{
private readonly AppConfig _appConfig;
private readonly ILogger<AirPorthttpClient> _logger;
private System.Net.Http.HttpClient _httpClient;
public string Url = "http://192.168.10.199:5102";
public AirPorthttpClient(AppConfig appConfig, ILogger<AirPorthttpClient> logger)
{
@ -34,51 +39,67 @@ namespace SlnMesnac.TouchSocket
_logger = logger;
}
public static WebApiClient AirportAGVClient;
private WebApiClient CreateWebApiClient(string IpHost)
{
var client = new WebApiClient();
try
{
_logger.LogInformation("正在连接:" + IpHost);
client.Connect(IpHost);
_logger.LogInformation(IpHost + "连接成功");
return client;
}
catch (Exception ex)
{
_logger.LogError("ERROR: " + ex.Message);
return null;
}
}
//private WebApiClient CreateWebApiClient(string IpHost)
//{
// var client = new WebApiClient();
// try
// {
// _logger.LogInformation("正在连接:" + IpHost);
// client.Connect(IpHost);
// _logger.LogInformation(IpHost + "连接成功");
// return client;
// }
// catch (Exception ex)
// {
// _logger.LogError("ERROR: " + ex.Message);
// return null;
// }
//}
public void init()
{
try
{
AirportAGVClient = CreateWebApiClient(_appConfig.AGVIpConfig);
}
catch (Exception ex)
{
_logger.LogError("ERROR: " + ex.Message);
}
_httpClient = new HttpClient();
}
/// <summary>
/// 获取到的JToken类型转换为实体类
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="value"></param>
/// <returns></returns>
public AGVResponseEntity<T> JTokenToEntity<T>(JToken value) where T : class
///// <summary>
///// 获取到的JToken类型转换为实体类
///// </summary>
///// <typeparam name="T"></typeparam>
///// <param name="value"></param>
///// <returns></returns>
//public AGVResponseEntity<T> JTokenToEntity<T>(JToken value) where T : class
//{
// if (value == null)
// {
// _logger.LogError("返回空数据!");
// return null;
// }
// string json = value.ToString();
// if (string.IsNullOrEmpty(json))
// {
// _logger.LogError("解析数据为空!");
// return null;
// }
// AGVResponseEntity<T> ResponseEntity;
// try
// {
// ResponseEntity = JsonSerializer.Deserialize<AGVResponseEntity<T>>(json);
// return ResponseEntity;
// }
// catch (Exception ex)
// {
// _logger.LogError($"Json反序列化发生错误{ex.Message}");
// return null;
// }
//}
public AGVResponseEntity<T> JsonStringToEntity<T>(string json) where T : class
{
if (value == null)
if (json == null)
{
_logger.LogError("返回空数据!");
return null;
}
string json = value.ToString();
if (string.IsNullOrEmpty(json))
{
_logger.LogError("解析数据为空!");
@ -87,7 +108,7 @@ namespace SlnMesnac.TouchSocket
AGVResponseEntity<T> ResponseEntity;
try
{
ResponseEntity = JsonSerializer.Deserialize<AGVResponseEntity<T>>(json);
ResponseEntity = JsonConvert.DeserializeObject<AGVResponseEntity<T>>(json);
return ResponseEntity;
}
catch (Exception ex)
@ -96,6 +117,8 @@ namespace SlnMesnac.TouchSocket
return null;
}
}
/// <summary>
/// AGV下发任务请求
/// </summary>
@ -104,12 +127,18 @@ namespace SlnMesnac.TouchSocket
///
public AGVResponseEntity<ResponseAddTaskDataEntity> AGVAddTaskRequest(AGVRequestAddTaskEntity requestValue)
{
if (AirportAGVClient == null)
if(_httpClient == null)
{
_logger.LogError("http服务为空");
return null;
}
JToken responseValue = AirportAGVClient.InvokeT<JToken>("POST:/api/task/addTask", null, requestValue);
return JTokenToEntity<ResponseAddTaskDataEntity>(responseValue);
//序列化输入数据
string json = Newtonsoft.Json.JsonConvert.SerializeObject(requestValue);
var context = new StringContent(json, Encoding.UTF8, "application/json");
var httpContent = _httpClient.PostAsync($"{Url}/api/task/addTask", context).ConfigureAwait(false).GetAwaiter().GetResult().Content;
string result = httpContent.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
//JToken responseValue = AirportAGVClient.InvokeT<JToken>("POST:/api/task/addTask", null, requestValue);
return JsonStringToEntity<ResponseAddTaskDataEntity>(result);
}
/// <summary>
@ -119,12 +148,18 @@ namespace SlnMesnac.TouchSocket
/// <returns></returns>
public AGVResponseEntity<object> AGVOperationalTaskRequest(AGVRequestOperationalTaskEntity requestValue)
{
if (AirportAGVClient == null)
if (_httpClient == null)
{
_logger.LogError("http服务为空");
return null;
}
JToken responseValue = AirportAGVClient.InvokeT<JToken>("POST:/api/task/operationalTask", null, requestValue);
return JTokenToEntity<object>(responseValue);
//序列化输入数据
string json = Newtonsoft.Json.JsonConvert.SerializeObject(requestValue);
var context = new StringContent(json, Encoding.UTF8, "application/json");
var httpContent = _httpClient.PostAsync($"{Url}/api/task/operationalTask", context).ConfigureAwait(false).GetAwaiter().GetResult().Content;
string result = httpContent.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
//JToken responseValue = AirportAGVClient.InvokeT<JToken>("POST:/api/task/operationalTask", null, requestValue);
return JsonStringToEntity<object>(result);
}
/// <summary>
@ -134,12 +169,18 @@ namespace SlnMesnac.TouchSocket
/// <returns></returns>
public AGVResponseEntity<ResponseTaskStateDetailDataEntity> AGVGetTaskStateDetailRequest(AGVRequestTaskStateDetailEntity requestValue)
{
if (AirportAGVClient == null)
if (_httpClient == null)
{
_logger.LogError("http服务为空");
return null;
}
JToken responseValue = AirportAGVClient.InvokeT<JToken>("PUT:/api/task/getTaskStateDetail", null, requestValue);
return JTokenToEntity<ResponseTaskStateDetailDataEntity>(responseValue);
//序列化输入数据
string json = Newtonsoft.Json.JsonConvert.SerializeObject(requestValue);
var context = new StringContent(json, Encoding.UTF8, "application/json");
var httpContent = _httpClient.PutAsync($"{Url}/api/task/getTaskStateDetail", context).ConfigureAwait(false).GetAwaiter().GetResult().Content;
string result = httpContent.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
//JToken responseValue = AirportAGVClient.InvokeT<JToken>("PUT:/api/task/getTaskStateDetail", null, requestValue);
return JsonStringToEntity<ResponseTaskStateDetailDataEntity>(result);
}
/// <summary>
@ -148,12 +189,16 @@ namespace SlnMesnac.TouchSocket
/// <returns></returns>
public AGVResponseEntity<List<ResponseRobotAtrributeDataEntity>> AGVAllStateRequest()
{
if (AirportAGVClient == null)
if (_httpClient == null)
{
_logger.LogError("http服务为空");
return null;
}
JToken responseValue = AirportAGVClient.InvokeT<JToken>("GET:/api/task/robot/getRobot", null);
return JTokenToEntity<List<ResponseRobotAtrributeDataEntity>>(responseValue);
//序列化输入数据
var httpContent = _httpClient.GetAsync($"{Url}/api/task/robot/getRobot").ConfigureAwait(false).GetAwaiter().GetResult().Content;
string result = httpContent.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
//JToken responseValue = AirportAGVClient.InvokeT<JToken>("GET:/api/task/robot/getRobot", null);
return JsonStringToEntity<List<ResponseRobotAtrributeDataEntity>>(result);
}
/// <summary>
@ -162,12 +207,15 @@ namespace SlnMesnac.TouchSocket
/// <returns></returns>
public AGVResponseEntity<ResponseActiveMapDataEntity> AGVMapActiveRequest()
{
if (AirportAGVClient == null)
if (_httpClient == null)
{
_logger.LogError("http服务为空");
return null;
}
JToken responseValue = AirportAGVClient.InvokeT<JToken>("GET:/api/v1.0.0/Maps/mapActive", null);
return JTokenToEntity<ResponseActiveMapDataEntity>(responseValue);
var httpContent = _httpClient.GetAsync($"{Url}/api/v1.0.0/Maps/mapActive").ConfigureAwait(false).GetAwaiter().GetResult().Content;
string result = httpContent.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
//JToken responseValue = AirportAGVClient.InvokeT<JToken>("GET:/api/v1.0.0/Maps/mapActive", null);
return JsonStringToEntity<ResponseActiveMapDataEntity>(result);
}
/// <summary>
@ -177,32 +225,68 @@ namespace SlnMesnac.TouchSocket
/// <returns></returns>
public AGVResponseEntity<List<ResponseMapPositionDataEntity>> AGVMapPositionRequest(string requestValue)
{
if (AirportAGVClient == null)
if (_httpClient == null)
{
_logger.LogError("http服务为空");
return null;
}
JToken responseValue = AirportAGVClient.InvokeT<JToken>("GET:/api/v1.0.0/Positions?mapId={0}", null, requestValue);
return JTokenToEntity<List<ResponseMapPositionDataEntity>>(responseValue);
//序列化输入数据
string json = Newtonsoft.Json.JsonConvert.SerializeObject(requestValue);
var context = new StringContent(json, Encoding.UTF8, "application/json");
var httpContent = _httpClient.GetAsync($"{Url}/api/v1.0.0/Positions?mapId={requestValue}").ConfigureAwait(false).GetAwaiter().GetResult().Content;
string result = httpContent.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
//JToken responseValue = AirportAGVClient.InvokeT<JToken>("GET:/api/v1.0.0/Positions?mapId={0}", null, requestValue);
return JsonStringToEntity<List<ResponseMapPositionDataEntity>>(result);
}
/// <summary>
/// 获取当前所有任务模板信息(目前不可用)
/// AGV异常获取清除
/// </summary>
/// <param name="agvIp"></param>
/// <returns></returns>
public AGVResponseEntity<object> AGVJobRequest()
public AGVResponseEntity<object> AGVErrorClear(string agvIp)
{
if (AirportAGVClient == null)
if (_httpClient == null)
{
_logger.LogError("http服务为空");
return null;
}
JToken responseValue = AirportAGVClient.InvokeT<JToken>("GET:/api/v1.0.0/Positions?mapId={0}", null);
return JTokenToEntity<object>(responseValue);
}
string token = "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiYWRtaW4iLCJyb2xlIjoiMSIsImlzcyI6IlNpbmV2YVNlcnZlciIsImF1ZCI6IlNpbmV2YUNsaWVudCJ9.Ujn-JuQDzA_sloITF84z1pdQvvH8DQ0DSFlhz4zP44M";
var request = new HttpRequestMessage(HttpMethod.Delete, $"http://{agvIp}/api/v1.0.0/ClearException/0");
// 单独为此请求添加 Authorization 头部
request.Headers.Add("Authorization", token);
// 发送请求
var response = _httpClient.SendAsync(request).ConfigureAwait(false).GetAwaiter().GetResult();
// 读取响应内容
var httpContent = response.Content;
string result = httpContent.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
return JsonStringToEntity<object>(result);
}
//HttpClient client1 = new HttpClient();
///// <summary>
///// 获取当前所有任务模板信息(目前不可用)
///// </summary>
///// <returns></returns>
//public AGVResponseEntity<object> AGVJobRequest()
//{
// if (_httpClient == null)
// {
// _logger.LogError("http服务为空");
// }
// //序列化输入数据
// string json = Newtonsoft.Json.JsonConvert.SerializeObject(requestValue);
// var context = new StringContent(json, Encoding.UTF8, "application/json");
// var httpContent = _httpClient.PostAsync($"{Url}/api/task/addTask", context).ConfigureAwait(false).GetAwaiter().GetResult().Content;
// string result = httpContent.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult();
// AGVResponseEntity<ResponseAddTaskDataEntity> responseEntity = JsonConvert.DeserializeObject<AGVResponseEntity<ResponseAddTaskDataEntity>>(result);
// //JToken responseValue = AirportAGVClient.InvokeT<JToken>("GET:/api/v1.0.0/Positions?mapId={0}", null);
// return JTokenToEntity<object>(responseValue);
//}
}
//string url = "http://192.168.10.199:5102/api/task/addTask";

@ -52,28 +52,34 @@
<Border Grid.Row="2" BorderBrush="Red" BorderThickness="0" CornerRadius="5" Background="Transparent" Margin="2,5,2,2">
<ContentControl Content="{Binding UserContent}"/>
</Border>
<Border Grid.Row="3" BorderBrush="#1254AB" BorderThickness="0" CornerRadius="5" Background="Transparent" Margin="6,2,6,7">
<Border Grid.Row="3" BorderBrush="#1254AB" BorderThickness="0" CornerRadius="5" Background="Transparent" Margin="6,0,6,7">
<Border.Effect>
<DropShadowEffect Color="#1254AB" Direction="270" BlurRadius="10" ShadowDepth="5" Opacity="0.5"/>
</Border.Effect>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="847*"/>
<ColumnDefinition Width="102*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Left" Orientation="Horizontal">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Orientation="Horizontal" Height="30" Width="1674">
<Button Content="首 页" x:Name="Index" Command="{Binding ControlOnClickCommand}" CommandParameter="{Binding Name,ElementName=Index}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="10,0,10,0"/>
<Button Content="代码生成" x:Name="Generate" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=Generate}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0"/>
<Button Content="发送开始抓取" x:Name="TestButton1" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=TestButton1}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0" Click="Button_Click_1"/>
<Button Content="发送结束抓取" x:Name="TestButton2" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=TestButton2}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0" Click="Button_Click_2"/>
<Button Content="调用小车" x:Name="TestButton3" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=TestButton3}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0" Click="Button_Click_3"/>
<Button Content="入库小车" x:Name="TestButton4" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=TestButton4}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0" Click="Button_Click_4"/>
<Button Content="键 盘" Command="{Binding OpenSystemKeyboardCommand}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0"/>
<Button Content="调用800小车" x:Name="TestButton3" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=TestButton3}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0" Click="Button_Click_3"/>
<Button Content="入库800小车" x:Name="TestButton4" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=TestButton4}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0" Click="Button_Click_4"/>
<Button Content="调用1000小车" x:Name="TestButton8" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=TestButton8}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0" Click="Button_Click_3"/>
<Button Content="入库1000小车" x:Name="TestButton9" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=TestButton9}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0" Click="Button_Click_4"/>
<Button Content="复位1000小车" x:Name="TestButton10" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=TestButton10}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0" Click="Button_Click_4"/>
<Button Content="手动停止任务" x:Name="TestButton5" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=TestButton5}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0" Click="Button_Click_5"/>
<Button Content="手动清除报警" x:Name="TestButton6" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=TestButton6}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0" Click="Button_Click_6"/>
<Button Content="流程开始" x:Name="TestButton7" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=TestButton7}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0" Click="Button_Click_7"/>
<!--<Button Content="键 盘" Command="{Binding OpenSystemKeyboardCommand}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#009999" BorderBrush="#FF36B5C1" Margin="0,0,10,0"/>-->
<Button Content="最小化" x:Name="Minimized" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=Minimized}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#FF9900" BorderBrush="#FF9900" Margin="0,0,10,0"/>
<Button Content="退 出" x:Name="Exit" Command="{Binding FormControlCommand}" CommandParameter="{Binding Name,ElementName=Exit}" Style="{StaticResource BUTTON_AGREE}" Width="100" Height="30" Background="#FF0033" BorderBrush="#FF0033" Margin="0,0,10,0"/>
</StackPanel>
<StackPanel Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Right" Orientation="Horizontal">
<StackPanel Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Orientation="Horizontal" Height="50" Margin="376,0,0,0" Width="253">
<!--多行状态显示-->
<Grid>

@ -64,5 +64,20 @@ namespace SlnMesnac.WPF
{
MessageBox.Show("入库小车");
}
private void Button_Click_5(object sender, RoutedEventArgs e)
{
MessageBox.Show("手动停止任务");
}
private void Button_Click_6(object sender, RoutedEventArgs e)
{
MessageBox.Show("手动清除报警");
}
private void Button_Click_7(object sender, RoutedEventArgs e)
{
MessageBox.Show("流程开始");
}
}
}

@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging;
using SlnMesnac.Business.@base;
using SlnMesnac.Config;
using SlnMesnac.Model.AirportApiEntity;
using SlnMesnac.Repository;
using SlnMesnac.Repository.service;
using SlnMesnac.TouchSocket;
using SlnMesnac.WPF.Page.Generate;
@ -14,6 +15,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace SlnMesnac.WPF.ViewModel
@ -24,9 +26,11 @@ namespace SlnMesnac.WPF.ViewModel
private readonly ILogger<BaseTaskInfoBusiness> _BaseTaskInfoBusinesslogger;
private readonly ILogger<BaseAGVBusiness> _baseAGVBusinessLogger;
private readonly ILogger<VisionBusiness> _VisionBusinessLogger;
private readonly ILogger<BaseStateRefreshBusiness> _StateRefreshBusinessLogger;
private IAirportTaskService _Taskservice;
private IAGVStateService _AGVStateService;
private IAGVMapPointService _AGVMapPointService;
private IAGVSettingService _AGVSettingService;
private TcpServer _tcpServer;
//代码生成
private readonly GenerateControl generateControl = new GenerateControl();
@ -34,6 +38,7 @@ namespace SlnMesnac.WPF.ViewModel
private AppConfig _appConfig;
private AirPorthttpClient _airPorthttpClient;
private BaseTaskInfoBusiness _baseTaskInfoBusiness;
private BaseStateRefreshBusiness _baseStateRefreshBusiness;
private BaseAGVBusiness _baseAGVBusiness;
private VisionBusiness _visionBusiness;
@ -103,15 +108,18 @@ namespace SlnMesnac.WPF.ViewModel
_appConfig = App.ServiceProvider.GetService<AppConfig>();
_logger = App.ServiceProvider.GetService<ILogger<MainWindowViewModel>>();
_BaseTaskInfoBusinesslogger = App.ServiceProvider.GetService<ILogger<BaseTaskInfoBusiness>>();
_baseAGVBusinessLogger = App.ServiceProvider.GetService<ILogger<BaseAGVBusiness>>();
_VisionBusinessLogger = App.ServiceProvider.GetService<ILogger<VisionBusiness>>();
_Taskservice = App.ServiceProvider.GetService<IAirportTaskService>();
_AGVStateService = App.ServiceProvider.GetService<IAGVStateService>();
_AGVMapPointService = App.ServiceProvider.GetService<IAGVMapPointService>();
_AGVSettingService = App.ServiceProvider.GetService<IAGVSettingService>();
_tcpServer = App.ServiceProvider.GetService<TcpServer>();
_airPorthttpClient = App.ServiceProvider.GetService<AirPorthttpClient>();
_baseTaskInfoBusiness = BaseTaskInfoBusiness.GetInstance(_BaseTaskInfoBusinesslogger, _Taskservice, _AGVStateService, _tcpServer, _airPorthttpClient);
_baseAGVBusiness = BaseAGVBusiness.GetInstance(_baseAGVBusinessLogger, _airPorthttpClient, _AGVStateService, _AGVMapPointService);
_visionBusiness = VisionBusiness.GetInstance(_VisionBusinessLogger, _tcpServer);
_baseStateRefreshBusiness = BaseStateRefreshBusiness.GetInstance(_StateRefreshBusinessLogger, _AGVStateService, _airPorthttpClient, _AGVSettingService);
ControlOnClickCommand = new RelayCommand<object>(obj => ControlOnClick(obj));
FormControlCommand = new RelayCommand<object>(x => FormControl(x));
_tcpServer.RefreshStateAction += (_clientIP, _state) =>
@ -121,6 +129,7 @@ namespace SlnMesnac.WPF.ViewModel
ShellScannerStatus = _state ? 1 : 2;
}
};
_baseStateRefreshBusiness.AGVStateUpdateTimerOperation(TimerControl.Start);
UserContent = indexContent;
}
@ -171,8 +180,7 @@ namespace SlnMesnac.WPF.ViewModel
break;
case "TestButton3":
//终止小车当前任务
_baseAGVBusiness.EndAGVTask(_appConfig.AGVConfig.Where(x => x.AGVName == "S800-B").First().AGVGUID);
Thread.Sleep(500);
StopTaskAndClearError("S800-B");
//调用小车到抓取位置
_baseAGVBusiness.DownloadTask(
_appConfig.AGVConfig.Where(x => x.AGVName == "S800-B").First().AGVGUID,
@ -183,8 +191,7 @@ namespace SlnMesnac.WPF.ViewModel
break;
case "TestButton4":
//终止小车当前任务
_baseAGVBusiness.EndAGVTask(_appConfig.AGVConfig.Where(x => x.AGVName == "S800-B").First().AGVGUID);
Thread.Sleep(500);
StopTaskAndClearError("S800-B");
//调用小车到库位
_baseAGVBusiness.DownloadTask(
_appConfig.AGVConfig.Where(x => x.AGVName == "S800-B").First().AGVGUID,
@ -193,13 +200,121 @@ namespace SlnMesnac.WPF.ViewModel
_appConfig.PositionConfig.Where(x => x.PointName == "800装货点").First().PointParamName
);
break;
case "TestButton8":
//终止小车当前任务
StopTaskAndClearError("S1000-A");
//调用小车到抓取位置
_baseAGVBusiness.DownloadTask(
_appConfig.AGVConfig.Where(x => x.AGVName == "S1000-A").First().AGVGUID,
_appConfig.JobConfig.Where(x => x.JobName == "1000小车进入位置任务pause").First().JobGUID,
_appConfig.PositionConfig.Where(x => x.PointName == "1000装货点").First().PointGUID,
_appConfig.PositionConfig.Where(x => x.PointName == "1000装货点").First().PointParamName
);
break;
case "TestButton9":
//终止小车当前任务
StopTaskAndClearError("S1000-A");
//调用小车到库位
_baseAGVBusiness.DownloadTask(
_appConfig.AGVConfig.Where(x => x.AGVName == "S1000-A").First().AGVGUID,
_appConfig.JobConfig.Where(x => x.JobName == "1000小车入库任务pause").First().JobGUID,
_appConfig.PositionConfig.Where(x => x.PointName == "1000装货点").First().PointGUID,
_appConfig.PositionConfig.Where(x => x.PointName == "1000装货点").First().PointParamName
);
break;
case "TestButton10":
//终止小车当前任务
StopTaskAndClearError("S1000-A");
//调用小车到库位
_baseAGVBusiness.DownloadTask(
_appConfig.AGVConfig.Where(x => x.AGVName == "S1000-A").First().AGVGUID,
_appConfig.JobConfig.Where(x => x.JobName == "1000校正模板").First().JobGUID,
_appConfig.PositionConfig.Where(x => x.PointName == "1000装货点").First().PointGUID,
_appConfig.PositionConfig.Where(x => x.PointName == "1000装货点").First().PointParamName
);
break;
case "TestButton5":
//手动停止任务
StopTaskAndClearError("S800-B");
break;
case "TestButton6":
//手动清除报警
ClaerError("S800-B");
break;
case "TestButton7":
BusinessShow();
break;
default:
break;
}
}
catch (Exception ex)
{
_logger.LogError("窗体控制逻辑异常", ex);
_logger.LogError("窗体控制逻辑异常" + ex.Message);
}
}
/// <summary>
/// 演示程序
/// </summary>
private void BusinessShow()
{
try
{
Task.Run(() =>
{
while (true)
{
Thread.Sleep(1000);
List<AGVState> lists = _AGVStateService.GetAllAGVState();
}
});
}
catch
{
}
}
/// <summary>
/// 结束任务并清除报警
/// </summary>
private void StopTaskAndClearError(string agvName)
{
try
{
Task.Run(() =>
{
_baseAGVBusiness.EndAGVTask(_appConfig.AGVConfig.Where(x => x.AGVName == agvName).First().AGVGUID);
Thread.Sleep(500);
_airPorthttpClient.AGVErrorClear(_appConfig.AGVConfig.Where(x => x.AGVName == agvName).First().AGVIp);
Thread.Sleep(500);
});
}
catch (Exception ex)
{
_logger.LogError("结束任务并清除报警发生异常 " + ex);
}
}
/// <summary>
/// 清除报警
/// </summary>
private void ClaerError(string agvName)
{
try
{
Task.Run(() =>
{
_airPorthttpClient.AGVErrorClear(_appConfig.AGVConfig.Where(x => x.AGVName == agvName).First().AGVIp);
Thread.Sleep(500);
});
}
catch(Exception ex)
{
_logger.LogError("清除报警发生异常 " + ex);
}
}

@ -81,34 +81,38 @@
"AGVConfig": [
{
"AGVGUID": "f3358c0cee904204a9d53323171f3d1d",
"AGVName": "S800-A"
"AGVName": "S800-A",
"AGVIp": "192.168.10.102"
},
{
"AGVGUID": "53773a420771497b8b699e949e9eaacb",
"AGVName": "S800-B"
"AGVName": "S800-B",
"AGVIp": "192.168.10.104"
},
{
"AGVGUID": "88db096830b74d1e92a5a3ec20e1da19",
"AGVName": "S1000-A"
"AGVName": "S1000-A",
"AGVIp": "192.168.10.103"
},
{
"AGVGUID": "85a8e57c9fdc45a89686f62f03f54489",
"AGVName": "S1000-B"
"AGVName": "S1000-B",
"AGVIp": "192.168.10.101"
}
],
"PositionConfig": [
{
"PointGUID": "87f1eb13d6fb48c0b18e87917b40f148",
"PointGUID": "8491f5771c824bab80a497cc9af63772",
"PointName": "800装货点",
"PointParamName": "p1"
},
{
"PointGUID": "a902cd2f69b942cba287e70c97f27616",
"PointGUID": "eea2fc77b5214aadb997d30ac0f586c4",
"PointName": "1000装货点",
"PointParamName": "p1"
},
{
"PointGUID": "87f1eb13d6fb48c0b18e87917b40f148",
"PointGUID": "f53a8eca76834c1d8cb2d02ed9738837",
"PointName": "卸货点",
"PointParamName": "p1"
}
@ -121,6 +125,18 @@
{
"JobGUID": "ccf742e56beb4ed18f2de640fdcc0827",
"JobName": "800小车入库任务pause"
},
{
"JobGUID": "5be844b06bbb4bfbb71e3813a9770a9d",
"JobName": "1000小车入库任务pause"
},
{
"JobGUID": "4ee967b8a086465e9b9453eedf17e0b1",
"JobName": "1000小车进入位置任务pause"
},
{
"JobGUID": "5e43baba09c44504b2b02be1ee4b5710",
"JobName": "1000校正模板"
}
],

Loading…
Cancel
Save