Files
zhaowei.huang a0dc1e6cd0 refactor: 插件 UI 从 WinForms 迁移到 CycleGUI,并修复代码质量问题
将 StandardScene 各插件的配置/监控窗体从 WinForms 迁移到 CycleGUI(删除 .Designer.cs/.resx,重写为 PanelBuilder 立即模式 UI,新增 CycleUiHelper 统一对话框)。

同时修复代码审核中的问题:
- 后台文件写入加锁 + try/catch(ButtonBoxManager / DoorManager,对齐 LoopViewer.SaveTasks 模式)
- CoderFieldsMetadata.cs 启用 #nullable enable,消除 CS8632 警告
- DummyCar 移除已废弃的 rightClickAction()/SetPosition()
- CarRemoteHelper.OpenVehicleWebPage 的 Process.Start 加 try/catch
- 重命名名不副实的 Mstsc()(现为打开网页)
- 统一弃元命名为 _
- TrafficInterlockViewer 改用稳定 Id(GUID)做选择/编辑,替代行索引
- csproj 改用 $(CGUILibDir) 解析 CycleGUI,绝对路径收敛到 Directory.Build.props

构建:dotnet build StandardScene.sln → 0 错误,30 警告(均为历史遗留)。
注:static 单例状态重构(审核第 8 项)暂未处理,留待单独任务。
2026-06-26 15:00:53 +08:00

253 lines
10 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using LessokajiWeaverUtilities.Utilities;
using SimpleLite.RCS;
using SimpleLite.RCS.CarTypes;
using SimpleLite.CADTools;
using SimpleLite.Props;
using SimpleLite.UI;
using SimpleCore;
using SimpleCore.Compiler;
using SimpleCore.Library;
using SimpleCore.PropType;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using StandardScene.Utils;
namespace StandardScene.CarTypes
{
class ArmCarSiteFields:KivaSiteFields
{
public bool putNeedTurn = false;
}
class ArmCarTrackFields:KivaTrackFields
{
}
class ArmCarPlanFields:KivaPlanFields
{
public bool charge = false;
}
// 自 VDA5050Car.cs 下沉至 CoreArmCar 的 siteFields 引用它(见下方 [TemplateTrackCoderSettings])。
// VDA5050 拆为独立 dll 后 ArmCar 留 Core,不能反依赖 VDA dll,故该字段类置于 Core。
class VDA5050SiteField : BasicSiteFields
{
public bool DI41 = false;
public int SleepTime = 0;
public bool workPlace = false;
}
//[TemplateTrackCoderSettings(
// priority = 1,
// templateString = "agv.BasicGo(${src.x},${src.y},${src.id},${dst.x},${dst.y},${dst.id}," +
// "${track.id},${track.Speed},${track.Reverse||(track.ReverseDst==dst.id)}," +
// "${track.CarDirectionBias},${track.EnableCarAbsoluteDirection},${track.CarAbsoluteDirection},${track.typeInfo});",
// siteFields = typeof(KivaSiteFields),
// trackFields = typeof(KivaTrackFields),
// planFields = typeof(KivaPlanFields))]
//[TemplateSiteCoderSettings(
// priority = 5,
// useVerb = "plan.action=='fetch'&&plan.curSeg==plan.segN-1",
// blockVerb = "true",
// templateString = "agv.Wait();agv.Fetch(\"${dst.name}\");agv.Wait();",
// siteFields = typeof(ArmCarSiteFields),
// trackFields = typeof(ArmCarTrackFields),
// planFields = typeof(ArmCarPlanFields))]
//[TemplateSiteCoderSettings(
// priority = 5,
// useVerb = "plan.action=='put'&&plan.curSeg==plan.segN-1",
// blockVerb = "true",
// templateString = "agv.Wait();agv.Put(${dst.putNeedTurn},\"${dst.name}\");agv.Wait();",
// siteFields = typeof(ArmCarSiteFields),
// trackFields = typeof(ArmCarTrackFields),
// planFields = typeof(ArmCarPlanFields))]
//[TemplateSiteCoderSettings(
// priority = 5,
// useVerb = "plan.action=='putEmpty'&&plan.curSeg==plan.segN-1",
// blockVerb = "true",
// templateString = "agv.Wait();agv.PutEmpty(\"${dst.name}\");agv.Wait();",
// siteFields = typeof(ArmCarSiteFields),
// trackFields = typeof(ArmCarTrackFields),
// planFields = typeof(ArmCarPlanFields))]
[TemplateSiteCoderSettings(
priority = 5,
useVerb = "plan.action=='pickFull'&&plan.curSeg==plan.segN-1",
blockVerb = "true",
templateString = "agv.Wait();agv.PickFull(\"${dst.name}\");agv.Wait();",
siteFields = typeof(ArmCarSiteFields),
trackFields = typeof(ArmCarTrackFields),
planFields = typeof(ArmCarPlanFields))]
[TemplateSiteCoderSettings(
priority = 5,
useVerb = "plan.action=='pickEmpty'&&plan.curSeg==plan.segN-1",
blockVerb = "true",
templateString = "agv.Wait();agv.PickEmpty(\"${dst.name}\");agv.Wait();",
siteFields = typeof(ArmCarSiteFields),
trackFields = typeof(ArmCarTrackFields),
planFields = typeof(ArmCarPlanFields))]
[TemplateSiteCoderSettings(
priority = 5,
useVerb = "plan.action=='putFull'&&plan.curSeg==plan.segN-1",
blockVerb = "true",
templateString = "agv.Wait();agv.PutFull(\"${dst.name}\");agv.Wait();",
siteFields = typeof(ArmCarSiteFields),
trackFields = typeof(ArmCarTrackFields),
planFields = typeof(ArmCarPlanFields))]
[TemplateSiteCoderSettings(
priority = 5,
useVerb = "plan.action=='putEmpty'&&plan.curSeg==plan.segN-1",
blockVerb = "true",
templateString = "agv.Wait();agv.PutEmpty(\"${dst.name}\");agv.Wait();",
siteFields = typeof(ArmCarSiteFields),
trackFields = typeof(ArmCarTrackFields),
planFields = typeof(ArmCarPlanFields))]
[TemplateSiteCoderSettings(
priority = 5,
useVerb = "plan.action=='MoveArm'&&plan.curSeg==plan.segN-1",
blockVerb = "true",
templateString = "agv.Wait();agv.MoveArm(${dst.MoveDirection});agv.Wait();",
siteFields = typeof(ArmCarSiteFields),
trackFields = typeof(ArmCarTrackFields),
planFields = typeof(ArmCarPlanFields))]
[TemplateSiteCoderSettings(
priority = 5,
useVerb = "dst.name=='charge'",
templateString = "agv.Wait();agv.ControlChargePort(true);agv.Wait();",
siteFields = typeof(ArmCarSiteFields),
trackFields = typeof(ArmCarTrackFields),
planFields = typeof(ArmCarPlanFields))]
[TemplateSiteCoderSettings(
priority = 5,
useVerb = "dst.name=='charge'&&plan.curSeg==0",
templateString = "agv.Wait();agv.ControlChargePort(false);",
siteFields = typeof(VDA5050SiteField))]
[CarType(Name = "ArmCar")]
[I18N.DocumentTranslation(Name = "ArmCar", locale = "en")]
public class ArmCar : GhostCar
{
public static async Task<ArmCar> Create()
{
var car = new ArmCar()
{
lstatus = "连接中",
address = "127.0.0.1",
name = $"Kiva",
haveCoordination = true,
speed = 0.3f,
};
return car;
}
private const float DrawWidth = 950, DrawLength = 650;
private readonly Pen orientPen = new Pen(Color.White, 3);
private bool twinkle = false;
protected override void draw(Graphics eGraphics)
{
try
{
float scale = 1;
var lineCap = new AdjustableArrowCap(5, 5, true);
orientPen.CustomEndCap = lineCap;
orientPen.StartCap = LineCap.RoundAnchor;
var alarmLevel = Commons.GetCarStatus(this, "AlarmLevel");
var soc = Commons.CarValue((Car)this, "Soc");
var electricCurrent = Commons.CarValue((Car)this, "ElectricCurrent");
var thresSpeed = Commons.CarValue(this, "ThresSpeed");
LadderLogic.FlipFlop(ref twinkle, 500, true, false);
Rectangle destRect = new Rectangle(
(int)((int)(-DrawWidth / 2) * scale),
(int)((int)(-DrawLength / 2) * scale),
(int)((int)DrawWidth * scale),
(int)((int)DrawLength * scale)
);
if (int.TryParse(alarmLevel, out var alarm) && alarm > 0)
{
eGraphics.FillRectangle(twinkle ? Brushes.DarkRed : Brushes.Green, destRect);
}
else if (alarmLevel == "-1" || this.siteID == -1)
eGraphics.FillRectangle(Brushes.LightSeaGreen, destRect);
else if (electricCurrent > 1)
eGraphics.FillRectangle(Brushes.YellowGreen, destRect);
else if (thresSpeed <= 0)
{
eGraphics.FillRectangle(twinkle ? Brushes.YellowGreen : Brushes.Green, destRect);
}
else if (soc < 25)
{
eGraphics.FillRectangle(twinkle ? Brushes.DarkRed : Brushes.LightSeaGreen, destRect);
}
else
eGraphics.FillRectangle(Brushes.Green, destRect);
eGraphics.DrawEllipse(Pens.Yellow, -160, -160, 320, 320);
eGraphics.DrawLine(orientPen, 0, 0, 480, 0);
}
catch (Exception e)
{
Diagnosis.Post("绘制小车异常" + ExceptionFormatter.FormatEx(e), "绘制小车异常", true);
}
}
public override string SetDisplayInfo()
{
try
{
var str = $"{name}({id})\n";
status.enums.TryGetValue("ChassisMode", out var manual);
var ms = manual == "0" ? "自动" : "手动";
status.enums.TryGetValue("Soc", out var soc);
str = $"{str}{ms}|soc:{soc}";
var alarmStr = Commons.GetCarStatus(this, "AlarmInfo");
if (alarmStr != "")
str = $"{str}|{alarmStr}";
//if (status.enums.TryGetValue("mAlarm", out var mAlarm) && mAlarm != "")
// str = $"{str}|M:{mAlarm}";
//var hasC = status.enums.TryGetValue("cAlarm", out var cAlarm) && cAlarm != "";
//if (mAlarm != "" && hasC)
// str = $"{str}|";
//if (hasC)
// str = $"{str}C:{cAlarm}";
//var L_step = status.enums.TryGetValue("ls", out var ls) && ls != "";
//if (L_step)
//{
// str = $"{str}|ls:{ls}";
//}
if (status.enums.TryGetValue("ElectricCurrent", out var electricCurrent) &&
!string.IsNullOrEmpty(electricCurrent))
{
var charging = float.Parse(electricCurrent) * 0.01f > 0 ? "充电中" : "未充电";
str = $"{str}|charge:{charging}";
}
var thresSpeed = Commons.CarValue(this, "ThresSpeed");
str = $"{str}{((thresSpeed <= 0) ? "|避障触发" : "")}";
return str;
}
catch (Exception e)
{
Console.WriteLine(e);
return "bad car";
}
}
[MethodMember(Name = "进入小车管理界面", Description = "在浏览器中打开小车 Web 页面")]
[I18N.DocumentTranslation(Name = "Open vehicle management page", Description = "Open the car's management page in browser", locale = "en")]
public void OpenVehicleManagementPage()
{
CarRemoteHelper.OpenVehicleWebPage(address);
}
}
}